我在相册和帖子之间有一对多的关系:
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 %>
答案 0 :(得分:1)
如果您使用嵌套属性,就像您一样,您无需循环浏览相关帖子进行创建。 (这就是嵌套属性的用途)
但是,您必须确保在参数中允许这些post_id
s。 这是最常见的错误之一(我自己已经做了几次)
所以,在你的控制器中:
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: []
)id
用于关联属性,否则每次编辑/更新时都会创建新关联params.require(:album).permit(..., ...,
)posts_attributes: [:id, ..., ...]
)注意:前端视图表单也必须正确设置。 An example can be found on this rails cast,您可以check the documentation了解有关此问题的更多信息。
我刚看到你的前端视图更新。您可以利用您已经使用的嵌套属性,并通过扩展相册的帖子进行解释,如下所示:
<%= f.fields_for :posts do |p| %>
<%= p.collection_select :post_id, Post.order(:name),:id,:name, include_blank: true %>
<% end %>
答案 1 :(得分:0)
代码的直接修复是......
#config/routes.rb
resources :albums do
match :posts, via: [:get, :patch], on: :member #-> url.com/albums/:id/posts
end
#app/controllers/albums_controller.rb
class AlbumsController < ApplicationController
def posts
@album = Album.find params[:id]
@posts = Post.all if request.get?
if request.patch?
@album.update album_params
@album.save
end
end
private
def album_params
params.require(:album).permit(post_ids: [])
end
end
这可以伴随collection_select
:
#app/views/albums/posts.html.erb
<%= form_for @album do |f| %>
<%= f.collection_select :post_ids, @posts, :id, :name %>
<%= f.submit %>
<% end %>
然而,这将不工作(我推测),因为你希望。
使用belongs_to
/ has_many
时,您只能匹配&#34;对&#34;关系。这意味着添加到singular_collection_ids
方法将覆盖belongs_to
记录中的任何现有Post
引用。
简而言之,如果您想更改(不添加)您的关联对象,它将会起作用。如果您想将现有posts
添加到album
,您必须使用以下代码。
您最好使用has_and_belongs_to_many
:
#config/routes.rb
resources :album do
resources :posts #-> url.com/albums/:album_id/posts/new
end
#app/models/album.rb
class Album < ActiveRecord::Base
has_and_belongs_to_many :posts
end
#app/models/post.rb
class Post < ActiveRecord::Base
has_and_belongs_to_many :albums
end
#app/controllers/albums_controller.rb
class AlbumsController < ApplicationController
def edit
@album = Album.find params[:id]
@posts = Post.all
end
def update
@album = Album.find params[:id]
@album.update album_params
end
private
def album_params
params.require(:album).permit(post_ids: [])
end
end
#app/views/albums/edit.html.erb
<%= form_for @album do |f| %>
<%= f.collection_select :post_ids, @posts, :id, :name %>
<%= f.submit %>
<% end %>