Rob*_*ers 31 ruby-on-rails associations scopes
Rails 4允许您has_many
像这样关系范围:
class Customer < ActiveRecord::Base
has_many :orders, -> { where processed: true }
end
Run Code Online (Sandbox Code Playgroud)
因此,只要您这样做,customer.orders
您只能获得已处理的订单.
但是如果我需要使where
条件动态呢?如何将参数传递给范围lambda?
例如,我只希望显示客户当前在多租户环境中登录的帐户的订单.
这是我得到的:
class Customer < ActiveRecord::Base
has_many :orders, (account) { where(:account_id => account.id) }
end
Run Code Online (Sandbox Code Playgroud)
但是,在我的控制器或视图中,我如何通过正确的帐户?在我执行以下代码时,请执行以下操作:
customers.orders
Run Code Online (Sandbox Code Playgroud)
我得到账户ID为1的所有订单,看似随意.
Мал*_*евъ 27
方法是为has_many
范围定义其他扩展选择器:
class Customer < ActiveRecord::Base
has_many :orders do
def by_account(account)
# use `self` here to access to current `Customer` record
where(:account_id => account.id)
end
end
end
customers.orders.by_account(account)
Run Code Online (Sandbox Code Playgroud)
该方法Association Extension
在Rails Association
页面的头部描述.
要Customer
在嵌套方法中访问记录,您只能访问self
对象,它应该具有当前Customer
记录的值.
rails的Sinse(大约5.1)你可以将模型范围与其他类型相同类型的has_many范围合并,例如,你可以在两个模型中编写如下相同的代码:
class Customer < ApplicationRecord
has_many :orders
end
class Order < ApplicationRecord
scope :by_account, ->(account) { where(account_id: account.id) }
end
customers.orders.by_account(account)
Run Code Online (Sandbox Code Playgroud)
小智 24
您传入已定义的类的实例.在您的情况下,您将传递客户,然后获得该帐户.
来自API http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
有时,在构建查询时访问所有者对象很有用.所有者作为参数传递给块.例如,以下关联将查找用户生日时发生的所有事件:
class User < ActiveRecord::Base
has_many :birthday_events, ->(user) { where starts_on: user.birthday },
class_name: 'Event'
end
Run Code Online (Sandbox Code Playgroud)
在您的示例中,它将是:
class Customer < ActiveRecord::Base
has_many :orders, ->(customer) { where(account_id: customer.account.id) }
end
Run Code Online (Sandbox Code Playgroud)