ruby-on-railsrubysqueel

ruby - evalulate code returned from another method


ruby 2 and rails 4

Consider this chunk of code:

Post.where{
  (created_by == user) & 
  (
    (group_id.in [1,2,3,4]) | (event_id.in [5,6,7,8])
  )
}

Which works fine on its own.

What I would like to do is take (group_id.in [1,2,3,4]) | (event_id.in [5,6,7,8]) and have this come from a local variable, or method, or block or something.

I have many queries and would like this bit of code contained in a single spot.

I have tried several things, like using a block with yield, Proc and lambas. I seem to keep getting stuck on: NameError (undefined local variable or method 'group_id')

Note: I am using squeel, which contains its own DSL which uses instance_eval for its blocks. Which should be fine because I can access via my{<method_name_here>}.

Here is what I have tried:

viewable_areas = lambda { (group_id.in [1,2,3,4]) | (event_id.in [5,6,7,8]) }

Post.where{
  (created_by == user) & 
  (
    my{viewable_areas.call}
  )
}

The best I can get is the: NameError (undefined local variable or method 'group_id')

I know there must be a way of handling this, its just not coming to mind right now.

Also the real code I am working with is much more complex than what I am describing here but I have simplified it for this example.


Solution

  • Use a named scope:

    class Post << ...
    
      scope :viewable_areas, lambda {|group_ids, event_ids| where{(group_id.in group_ids) | (event_id.in event_ids)}
    
    end
    
    Post.viewable_areas([1,2,3,4],[5,6,7,8]).where{created_by == user}
    

    concatenation of where calls acts like &