如何连接两个活动记录结果以返回可以进一步过滤的新结果?
想象一下场景……
#models/user.rb class User { :active => 1 } end #models/account.rb class Account { public => true } end end
现在想象一下,我想将User(.id).accounts与Account.public_accounts连接起来,以显示用户可用的所有帐户的列表。
所以你认为我能够将User模型更新为这样。
#models/user.rb class User { :active => 1 } def all_accounts self.accounts + Account.public end end
但是,现在我将无法使用all()方法,因为它不再是那种类型的对象。
在控制器中我想这样做……
#controllers/accounts_controller.rb def search_all User.find(params[:user_id]).all_accounts.all( :offset => params[:offset], :limit => params[:limit] ) end
思考?
更新#1:范围不适用于我的方案。 我简化了我的方案,尝试着解决我的观点。 如上所述,我需要一种方法来组合两个活动记录结果,并保留在我的控制器中进一步过滤它们的能力。
所以问题是,“为什么?” 原因是,我试图将两组记录组合成一个完整的集合,其中一个集合根本不与用户相关联。
我已经重构了上面的场景,试图展示一个更精确的例子而不会过于复杂。
jklina的答案是正确的,在这种情况下最好使用范围。 范围提供了含糖的语法,并且更具可读性。 我将详细说明设置:
class User < AR::Base has_many :accounts end class Account < AR::Base belongs_to :user scope :active, where(:active => true) scope :inactive, where(:active => false) end
然后,您将访问帐户范围,如jklina所示: User.find(1).accounts.active
等。访问所有用户的帐户,如: User.find(1).accounts
。
更新:
我修正了一些错误并在下面添加了更多内容。
根据您的问题的更新,我认为您需要将public
方法作为类的方法:
class Accounts < AR::Base ... # This is essentially a scope anyways def self.public where(:public => true) end end class User < AR::Base ... # This should return all the users accounts # and any public accounts def all_accounts Account.where("user_id = ? OR public is true", self.id) end end
这可能是使用范围的好方案。
您可以在帐户模型中定义活动和非活动范围,然后使用以下内容:
User.accounts User.accounts.active User.accounts.inactive
您甚至可以将范围链接在一起,因此您可以执行以下操作:
User.accounts.active.paid_up
让我们看一下链中的返回值:
User.find(params[:user_id]) # returns an instance of User class User.find(params[:user_id]).all_accounts # returns an array
Array类没有名为all
的实例方法,这就是您看到此错误的原因。 这不是一个错误。
你为什么不试试这个:
class User has_many :accounts, :conditions => { :active => 1 } has_many :all_accounts :conditions => ["(active = ? OR public = ?)", true, true] end
现在你可以:
User.find(params[:user_id]).all_accounts.all(:limit => 10, :offset => 2)
您尝试访问两个不同的表并将LIMIT / OFFSET作为组合联合应用于它们。 除非您在SQL层逻辑上将它们组合在一起,而不是在ActiveRecord层,否则不会发生这种情况。
听起来像写出SQL,可能使用UNION
然后使用find_by_sql
可能是你最好的。
- 为什么ActiveRecord :: StatementInvalid:SQLite3 :: SQLException:near“)”:语法错误:INSERT INTO“user_friendships”()VALUES()
- has_many关系的每个最后元素的范围
- rails关联方法如何工作?
- 具有不同日期/时间格式的ActiveRecord
- Rails:uniq vs. distinct
- 您将如何使用rails和ActiveRecord中的引用和引用对文章进行建模?
- Ruby on Rails在哪里查询关系
- ActiveRecord按外部数组排序
- Rails:仅当另一个字段存在时才validation字段