我已经重写了 ActiveRecord::Base
的 find
方法,效果非常好,现在我可以很好地自定义它。
def self.find(*args)
# my custom actions
super(*args)
end
然后
Album.find(1) #=> My custom result
但现在我想重写这个:
Album.first.photos
而且我不确定我应该重写什么方法来完成工作...... 我正在考虑一些专门用于关联查询的东西,但我不确定:(
我需要对建议动态类的“ActiveRecord::Base”采取行动,因此我无法为此创建方法photos
,而是创建一个可以在我尝试的所有模型中进行交互的方法。
非常感谢
更新
为了更好地解释我想要实现的目标:
是创建一个可插入的 ruby gem 与 Rails 一起使用,该 gem 可以简单地从数据库中获取 ID 结构,并将其即时转换为缩短的 ID,就像 bit.ly 一样。系统。但这是动态完成的,只需向模型声明 has_shortened :id
,然后所有接口(interface)和查询都会返回例如 DH3
而不是 12
例如,我已经设法让它工作,这就是我需要处理关联的点。
关注 gem url http://github.com/ludicco/shortener因此您可以查看一下,如果您认为这是一个好主意,请随意提出可能需要实现的想法。
干杯
最佳答案
像您用has_many
定义的关联访问器在ActiveRecord中是非常复杂的东西。他们实际上使用反射类返回一个行为类似于模型类的代理对象,但将其查找器限制为外键(可能还有其他条件)。如果您想更深入地了解它,您可能需要查看 ActiveRecord gem 中的 Reflection.rb、association.rb、association/association_proxy.rb 和 Associations/association_collection.rb。
但是,最后,我们可以使用关联访问器,就像它是类本身一样,并且 ActiveRecord 会小心地将所需的附加条件传递给类查找器。
这意味着,如果您在幕后调用 Album.first.photos
,ActiveRecord 会调用 Photo.find
(附加条件是仅返回具有以下条件的记录: album_id => Album.first.id)。
因此,如果您重写 Photo.find
,并且通过 Album.first.photos
使用它,它也会返回修改后的结果。这就是 ActiveRecord 的魔力:)
我的快速测试(使用 Rails 2.3.8 运行):
class Album < ActiveRecord::Base
has_many :photos
end
class Photo < ActiveRecord::Base
belongs_to :album
def self.find (*args)
puts "XXX running custom finder"
super
end
end
Rails 控制台:
> Photo.all
XXX running custom finder
Photo Load (0.4ms) SELECT * FROM "photos"
=> [#<Photo id: 1, album_id: 1>, … ]
> Album.first.photos
Album Load (0.4ms) SELECT * FROM "albums" LIMIT 1
XXX running custom finder
Photo Load (0.3ms) SELECT * FROM "photos" WHERE ("photos".album_id = 1)
=> [#<Photo id: 1, album_id: 1>, … ]
关于ruby-on-rails - Ruby on Rails - 我应该为 Album.first.photos 重写哪个方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3305075/