Squeel and rails… dynamic where clause

情到浓时终转凉″ 提交于 2019-12-01 22:10:37

You need to programmatically build the Squeel query. For example:

def self.with_conditions(conditions)
  conditions.map do |col, str|
    Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub.new(col), :matches, str) # (email.matches "user@example.com")
  end.inject do |t, expr|
    t & expr # joins each expression from the .map above with & - to be converted to AND in the sql
  end.tap do |block|
    return where{(block)} # pass the constructed expression to Squeel
  end
end

On my User::User model I can run

User::User.with_conditions({email: "user@example.com", first_name: "Deefour"}).to_sql

and I will get

SELECT "user_users".* FROM "user_users"  WHERE (("user_users"."email" LIKE 'user@example.com' AND "user_users"."first_name" LIKE 'Deefour'))

I don't know if this helps, but I did it this way using this helper method:

  def query_for_matches(key, value)
    stub = Squeel::Nodes::Stub.new(key)
    Squeel::Nodes::Predicate.new(stub, :matches, "%#{value}%")
  end

You have a hash of parameters from a request of something:

  dynamic_params = {'username' => 'some_name', 'email' => 'email@example.com'}

Then I use this with a chain of where's in a loop:

  query = SomeModel #could be User, etc
  dynamic_params.each_pair {|key,value| query = query.where(query_for_matches(key, value)) }

You can then pass query to your view or whatever. I've only been on rails for a couple of weeks so I'm not sure if this is a best practice but it works.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!