如何使用Rails的belongs_to默认选项

问题描述 投票:0回答:1

我试图在获取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

ruby-on-rails rails-activerecord
1个回答
0
投票

聚会有点晚了,但希望这可以帮助任何像我一样进行搜索的人。

根据 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
© www.soinside.com 2019 - 2024. All rights reserved.