我试图在获取belongs_to关联记录之前执行一些逻辑,就像这个人为的示例:
# == Schema Information
#
# Table name: blogs
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
#
class Blog < ApplicationRecord
end
# == Schema Information
#
# Table name: posts
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# blog_id :integer
#
class Post < ApplicationRecord
belongs_to :blog, default: -> {
puts 'here'
Blog.first
}
end
通过这样做
post.blog
我期待获得第一个博客并看到“此处”的文本(在 Rails 控制台中执行此操作)
相反,我从 post.blog_id 获取实际的博客。
我在这里做错了什么以及在调用关联时如何执行一些 Ruby 逻辑? (范围对我不起作用,因为我想做 AR 查询以外的事情)
编辑:这里的 ActiveRecord 测试让我相信我的假设是正确的,上面的代码应该按我的预期工作https://github.com/rails/rails/blob/main/activerecord/test/cases/associations/belongs_to_associations_test .rb#L186
聚会有点晚了,但希望这可以帮助任何像我一样进行搜索的人。
根据 Rails Guide,
belongs_to
上的默认选项是一个布尔值,用于确定是否在验证中检查关联的存在。这可能支持验证后默认值。
我实现这样的关联默认值的方法是重写属性的 get 方法,例如
belongs_to :blog, optional: true
# If the blog association is blank, get the first blog
def blog
@blog ||= super || Blog.first
end
这只在直接调用
blog
时有效。这实际上并不默认数据库中的关联,因此 ActiveRecord 数据库操作(例如 where
、joins
、select
等)将不工作。
为此,建议使用
before_create
回调来设置默认值,例如
belongs_to :blog, default: true
before_create :set_blog
def set_blog
self.blog ||= Blog.first
end