我正在使用 Rails 7。我有模型 Post、Venue 和 VenuePost 模型。它们看起来如下:
class Post < ApplicationRecord
has_many :venue_posts, dependent: :destroy
accepts_nested_attributes_for :venue_posts
end
class Venue < ApplicationRecord
has_many :venue_posts, dependent: :destroy
end
class VenuePost < ApplicationRecord
belongs_to :post
belongs_to :venue
end
现在,我的帖子#new 操作如下所示:
def new
@post = Post.new
Venue.all.each do |v|
vp = @post.venue_posts.build(venue: v)
v.venue_posts << vp
end
end
问题是,即使我不调用创建操作,帖子仍然会保存到数据库中并将显示在索引页面上。为什么会这样,我怎样才能防止它,同时仍然保持我现在的相同行为,即在创建新帖子时为每个地点实例化一个 VenuePost 并能够在表单中编辑它并保存它。
感谢您的阅读
我相信
<<
会导致记录保存,这至少是由文档暗示的。
而不是为每个
Post
实例化 Venue
,您应该能够进行以下调整
class Post < ApplicationRecord
has_many :venue_posts, dependent: :destroy
has_many :venues, through: :venue_posts
end
class Venue < ApplicationRecord
has_many :venue_posts, dependent: :destroy
has_many :posts, through: :venue_posts
end
在控制器操作中
def new
Venue.all.each {|v| v.posts.build}
end
<<
方法确实保存了新记录,解释起来有点微妙:
通过将外键设置为关联的主键,将一条或多条记录添加到集合中。由于
展平其参数列表并 插入每条记录 ,因此推送和连接的行为相同。返回 self,因此多个附加可以链接在一起。<<
也许这会让事情变得更清楚一点:
post = Post.new #=> #<Post:0x00007fdbc7279610 id: nil>
venue_post = post.venue_posts.build(venue: Venue.first)
venue_post.post #=> #<Post:0x00007fdbc7279610 id: nil>
# when you save venue_post the new post is also saved
venue_post.save
#=>
# TRANSACTION (0.1ms) begin transaction
# Post Create (0.4ms) INSERT INTO "posts" DEFAULT VALUES RETURNING "id"
# VenuePost Create (0.1ms) INSERT INTO "venue_posts" ("venue_id", "post_id") VALUES (?, ?) RETURNING "id" [["venue_id", 1], ["post_id", 5]]
# TRANSACTION (0.1ms) commit transaction
这就是当您使用
<<
但对于所有场地帖子时会发生的情况。
据我所知,您根本不需要
v.venue_posts << vp
这部分,因为您只是为表单构建新记录。但你想在这里使用 has_many through:
关联: