Spr*_*ofi 5 activerecord ruby-on-rails has-many ruby-on-rails-3
我有一个游戏模型has_many:文本.问题是我必须根据他们属于哪个游戏来区分不同的文本(是的,丑陋的,但它是遗留数据).我创建了一个Text.in_game_order_query(game)方法,它返回适当的顺序.
我最喜欢的解决方案是在Text模型中放置一个默认范围,但这需要知道它们属于哪个游戏.我也不想为每个游戏的文本创建单独的类 - 有很多游戏,有更多的游戏,所有较新的游戏将使用相同的顺序.所以我有另一个想法:在has_many中订购文本,当我知道它们属于哪个游戏时:
has_many :texts, :order => Text.in_game_order_query(self)
Run Code Online (Sandbox Code Playgroud)
但是,self就是这里的类,所以这不起作用.
除了@game.texts.in_game_order(@game)每次呼叫之外,真的没有其他解决方案吗?
最近我遇到了一个非常相似的问题,我坚信在Rails中不可能实现,但是我学到了一些非常有趣的东西。
您可以为作用域声明一个参数,然后不传入该参数,默认情况下它将传入父对象!
因此,您可以执行以下操作:
class Game < ActiveRecord
has_many :texts, -> (game) { Text.in_game_order_query(game) }
Run Code Online (Sandbox Code Playgroud)
信不信由你,你不必通过游戏。Rails会为您神奇地做到这一点。您可以简单地执行以下操作:
game.texts
Run Code Online (Sandbox Code Playgroud)
不过,有一个警告。如果启用了预加载,则此功能目前在Rails中不起作用。如果这样做,您可能会收到以下警告:
声明警告:关联范围“文本”是实例相关的(范围块带有一个参数)。预加载在创建各个实例之前进行。这意味着没有实例传递到关联范围。这很可能导致故障或错误行为。这些关联的加入,预加载和急切加载已弃用,以后将被删除。
tho*_*ler -1
我认为如果您想要处理运行时信息,您应该通过以下方式完成此操作:
has_many :texts, :order => proc{ {Text.in_game_order_query(self)} }
Run Code Online (Sandbox Code Playgroud)