我在相册和帖子之间有一对多的关系:
class Post < ActiveRecord::Base
belongs_to :album
class Album < ActiveRecord::Base
has_many :posts, dependent: :destroy
accepts_nested_attributes_for :posts
在 AlbumsController
中,我想创建一个方法来将帖子添加到此关系(到 Album.posts
):
def add_post
@album = Album.find(params[:album_id])
params['album']['post_ids'].each do |post_id|
@album.posts << Post.find(post_id)
end
end
为什么不起作用?这样做的正确方法是什么?我也试过将 @album.id
分配给帖子的 album_id
列,但它也没有做任何事情。
表单如下所示:
<%= form_for :album, url: album_add_post_path(@album), method: :patch do |f| %>
<% @posts.each do |post| %>
<%= check_box_tag :post_ids, post.id, @album.posts.include?(post), :name => 'album[post_ids][]' %>
<% end %>
<%= f.submit class:"btn btn-success"%>
<% end %>
最佳答案
如果您正在使用嵌套属性,就像您一样,您不必遍历关联的帖子来创建。 (这就是嵌套属性的用途)
但是,您必须确保在参数中允许使用这些 post_id
。 这是最常见的错误之一(我自己也犯过几次)
所以,在你的 Controller 中:
def add_post
@album = Album.find(params[:album_id])
@album.update(album_params)
end
其中album_params
方法如下:
def album_params
params.require(:album).permit(..., ..., ..., posts_attributes: [:id, ..., ...])
end
这里要注意的重要事项:
- posts_attributes 作为所有关联属性的属性数组出现 (
posts_attributes: []
) - 关联属性应允许
id
,否则每次编辑/更新时都会创建新的关联 - 需要允许的父对象 ( album ) 的所有属性都直接列在 permit block 中 (
params.require(:album).permit(..., ...,
) - 需要允许的子对象 ( post ) 的所有属性都列在嵌套属性 block 中。 (
posts_attributes: [:id, ..., ...]
)
NOTE: The front-end view form has to be set right as well. An example can be found on this rails cast, And you can check the documentation for more information on this.
我刚刚看到您对前端 View 的更新。您可以利用您已经在使用的嵌套属性,我已经通过扩展相册的帖子进行了解释,如下所示:
<%= f.fields_for :posts do |p| %>
<%= p.collection_select :post_id, Post.order(:name),:id,:name, include_blank: true %>
<% end %>
关于ruby-on-rails - Rails 将元素添加到一对多关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34974753/