dza*_*jic 236 activerecord ruby-on-rails relation
如果我有一个带有lambda的范围并且它接受一个参数,取决于参数的值,我可能知道不会有任何匹配,但我仍然想要返回一个关系,而不是一个空数组:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
Run Code Online (Sandbox Code Playgroud)
我真正想要的是一种"无"方法,与"所有"相反,它返回一个仍然可以链接的关系,但会导致查询被短路.
ste*_*eh7 457
Rails 4中现在有一个"正确"的机制:
>> Model.none
=> #<ActiveRecord::Relation []>
Run Code Online (Sandbox Code Playgroud)
ste*_*eh7 76
一个更便携的解决方案,不需要"id"列,并且不会假设不会有id为0的行:
scope :none, where("1 = 0")
Run Code Online (Sandbox Code Playgroud)
我还在寻找一种更"正确"的方式.
Bra*_*don 42
您可以添加名为"none"的范围:
scope :none, where(:id => nil).where("id IS NOT ?", nil)
Run Code Online (Sandbox Code Playgroud)
那会给你一个空的ActiveRecord :: Relation
您也可以在初始化程序中将它添加到ActiveRecord :: Base(如果需要):
class ActiveRecord::Base
def self.none
where(arel_table[:id].eq(nil).and(arel_table[:id].not_eq(nil)))
end
end
Run Code Online (Sandbox Code Playgroud)
有很多方法可以获得这样的东西,但肯定不是保留在代码库中的最佳方法.我使用范围:无重构时发现我需要保证一个空的ActiveRecord :: Relation很短的时间.
小智 24
scope :none, limit(0)
Run Code Online (Sandbox Code Playgroud)
是一种危险的解决方案,因为您的范围可能会受到限制.
User.none.first
将返回第一个用户.它使用起来更安全
scope :none, where('1 = 0')
Run Code Online (Sandbox Code Playgroud)
Ale*_*lex 14
我认为我更喜欢这种方式与其他选项:
scope :none, limit(0)
Run Code Online (Sandbox Code Playgroud)
导致这样的事情:
scope :users, lambda { |ids| ids.present? ? where("user_id IN (?)", ids) : limit(0) }
Run Code Online (Sandbox Code Playgroud)