如何在Rails 3的范围ActiveRecord关联?
-
18-09-2019 - |
题
我有一个Rails 3项目。使用Rails 3来阿雷尔和能力重用一个范围再建。我想知道是否有定义关系(如“的has_many”)时使用范围的一种方式。
我有权限列的记录。我想建立一个default_scope这需要我的允许列考虑,这样的记录(即使是那些通过关系访问)进行过滤。
目前,在导轨3,default_scope(包括补丁我发现)不提供传递一个PROC(我需要后期可变结合)的一个可行的方法。是否有可能限定到其中一个命名范围可以传递一个的has_many?
重用命名范围看起来像的想法:
Orders.scope :my_orders, lambda{where(:user_id => User.current_user.id)}
has_many :orders, :scope => Orders.my_orders
或隐式编码名为范围的关系将是这样的:
has_many :orders, :scope => lambda{where(:user_id => User.current_user.id)}
我只是想用后期绑定适用default_scope。我宁愿使用阿雷尔方法(如果有的话),但会使用任何可行的选择。
由于我指的是当前用户,我不能依靠未在最后可能的时刻进行评价条件,如:
has_many :orders, :conditions => ["user_id = ?", User.current_user.id]
解决方案
我建议你看一看“命名范围都死了“
作者解释有阿雷尔多么强大:)
我希望这会帮助你。
EDIT#2014 3月1日
作为一些评论状态,所不同的是现在的个人喜好。
但是,我还是个人推荐,以避免暴露阿雷尔的范围到上层(即控制器或其他任何直接访问模型),并且这样做需要:
- 创建一个范围,并将其公开通在模型中的方法。该方法将是您暴露到控制器的一个;
- 如果您从未暴露你的模型,你的控制器(让你有某种在它们之上的服务层),那么你的罚款。反腐败层的是的服务,它可以不用太担心作用域是如何实现的访问模式的范围。 醇>
其他提示
如何关联的扩展?
class Item < ActiveRecord::Base
has_many :orders do
def for_user(user_id)
where(user_id: user_id)
end
end
end
Item.first.orders.for_user(current_user)
更新:我想的优点指出到关联的扩展,而不是类方法或作用域是可以访问的关联代理的内部:
这里proxy_association.owner返回该关联的一部分的对象。 proxy_association.reflection返回描述关联的反射物体。 proxy_association.target返回相关的对象belongs_to的或HAS_ONE,或用于的has_many或has_and_belongs_to_many相关联的对象的集合。
的更多细节: http://guides.rubyonrails.org/association_basics.html#关联的扩展
相反,我刚刚被定义类的方法范围,它一直致力于伟大的
def self.age0 do
where("blah")
end
我使用类似:
class Invoice < ActiveRecord::Base
scope :aged_0, lambda{ where("created_at IS NULL OR created_at < ?", Date.today + 30.days).joins(:owner) }
end
可以使用以便从不同的模型合并范围合并方式。 详情搜索合并在此 railscast
如果你只是想获得用户的订单,你为什么不只是使用的关系?
假定该当前用户是从在控制器的CURRENT_USER方法可访问:
@my_orders = current_user.orders
这不仅保证用户的特定命令将被显示。你也可以做任意嵌套的联接使用joins
得到更深层次的资源
current_user.orders.joins(:level1 => { :level2 => :level3 }).where('level3s.id' => X)