例如,假设您在保存之前始终保留用户电子邮件。
要查找,
User.find_by(email: params[:email].downcase)
但我不想每次发现时都要编写代码。
另外,我不想要不区分大小写的搜索。
而且,它应该是可组合的,并且可以在哪里工作。例如,
User.where(email: params[:email], status:'active')
答案 0 :(得分:3)
您可以为此定义范围:
class User < ActiveRecord::Base
scope :with_email, lambda { |email| where(email: email.downcase) }
并像这样使用它:
User.with_email(params[:email]).where(status: 'active')
最终你可以这样做:
# in User model
def self.normalized_search(search_attrs = {})
searchable_attributes = [:username, :email, :first_name, :last_name]
scope = self.scoped
search_attrs.each do |attr, value|
next unless searchable_attributes.include?(attr.to_sym)
next if value.blank?
scope = scope.where(attr.to_sym => value.to_s.downcase)
end
scope
end
然后你可以使用:
User.normalized_search({email: 'HeyHo@santa.com', username: 'Santa'})
此代码非常灵活:您可以轻松添加/删除属性以允许对其进行搜索,您可以轻松地替换链式where
(在每个之间添加&#34; AND&#34;子句)到手动编写的SQL查询与&#34; OR&#34;等等。
如果您希望每次都使用默认范围(几乎),使用列的值,您可以使用default_scope
:
class User < ActiveRecord::Base
default_scope { where(is_admin: false) }
然后调用User.where(something: some_variable)
将排除User
is_admin
true
的{{1}}条记录。要忽略默认范围,请使用User.unscoped.where(...)
。
有关default_scope
的更多信息:http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html