gpt4 book ai didi

ruby-on-rails - Ruby on Rails - 我应该为 Album.first.photos 覆盖哪种方法?

转载 作者:数据小太阳 更新时间:2023-10-29 08:55:09 24 4
gpt4 key购买 nike

我已经为 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、associations.rb、associations/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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com