我无法使用accepts_nested_attributes_for创建模型对象。 它不会创建嵌套对象

我的模型结构如下所示:

董事会has_many主题。 主题has_manypost。

应用程序/模型/ board.rb

class Board < ActiveRecord::Base has_many :topics end 

应用程序/模型/ topic.rb

 class Topic < ActiveRecord::Base belongs_to :user belongs_to :board has_many :posts accepts_nested_attributes_for :posts validates :title, presence: true, length: { maximum: 255 } validates :user_id, presence: true validates :board_id, presence: true ... end 

应用程序/模型/ post.rb

 class Post < ActiveRecord::Base belongs_to :user belongs_to :topic validates :user_id, presence: true validates :topic_id, presence: true validates :content, length: { minimum: 8 } end 

以下是我创建新主题的观点。 fields_for部分用于在新post上创建:内容

应用程序/视图/主题/ new.html.erb

 

在创建新主题时,我想要一个新post,其中包含来自表单的内容也可以创建。 由于post依赖于主题以便有效,因此需要同时创建或拒绝它们(如果:content或:title无效)。 有人告诉我,accepts_nested_attributes_for可以正常工作,但是当我的代码执行时,它只会创建主题,而不是Post。

应用程序/控制器/ topics_controller.rb

 def new @board = Board.find(params[:board_id]) @topic = @board.topics.build @post = @topic.posts.build end def create @board = Board.find(params[:board_id]) @topic = @board.topics.build(topic_params.merge({user_id: current_user.id})) if @topic.save flash[:success] = "Topic created" redirect_to @topic else render 'new' end end private def topic_params params.require(:topic).permit(:title, posts_attributes: [:content]) end 

对于记录,这是我的post控制器和路线,如果它有帮助。

应用程序/控制器/ posts_controller.rb

 def create @topic = Topic.find(params[:topic_id]) @post = @topic.posts.build(post_params.merge({user_id: current_user.id})) if @post.save flash[:success] = "Post Created" redirect_to topic_path(@topic) else render 'new' end end private def post_params params.require(:post).permit(:content) end 

董事会,主题和职位的耙路线

  topic_posts GET /topics/:topic_id/posts(.:format) posts#index POST /topics/:topic_id/posts(.:format) posts#create new_topic_post GET /topics/:topic_id/posts/new(.:format) posts#new edit_post GET /posts/:id/edit(.:format) posts#edit post GET /posts/:id(.:format) posts#show PATCH /posts/:id(.:format) posts#update PUT /posts/:id(.:format) posts#update DELETE /posts/:id(.:format) posts#destroy board_topics GET /boards/:board_id/topics(.:format) topics#index POST /boards/:board_id/topics(.:format) topics#create new_board_topic GET /boards/:board_id/topics/new(.:format) topics#new edit_topic GET /topics/:id/edit(.:format) topics#edit topic GET /topics/:id(.:format) topics#show PATCH /topics/:id(.:format) topics#update PUT /topics/:id(.:format) topics#update DELETE /topics/:id(.:format) topics#destroy boards GET /boards(.:format) boards#index POST /boards(.:format) boards#create new_board GET /boards/new(.:format) boards#new edit_board GET /boards/:id/edit(.:format) boards#edit board GET /boards/:id(.:format) boards#show PATCH /boards/:id(.:format) boards#update PUT /boards/:id(.:format) boards#update DELETE /boards/:id(.:format) boards#destroy 

还有在topic_controller #start开头的params的值

{“utf8”=>“✓”,“authenticity_token”=>“…”,“topic”=> {“title”=>“新标题”,“发布”=> {“content”=>“新内容“}},”提交“=>”发布新主题“,”操作“=>”创建“,”控制器“=>”主题“,”board_id“=>”1“}

终于找到了解决方案

这是在我修复表格以正确创建参数之后。

基本上,我需要在我的模型上使用:inverse_of 。 我真的不明白这实现了什么,但它有效。 这是我的代码

topic.rb

 class Topic < ActiveRecord::Base belongs_to :user belongs_to :board has_many :posts, :inverse_of => :topic accepts_nested_attributes_for :posts validates :title, presence: true, length: { maximum: 255 } validates :user, presence: true validates :board, presence: true end 

post.rb

 class Post < ActiveRecord::Base belongs_to :user belongs_to :topic, :inverse_of => :posts validates :user, presence: true validates :topic, presence: true validates :content, presence: true end 

应用程序/视图/主题/ new.html.erb

 
<%= form_for [@board, @topic] do |f| %> <%= render 'shared/error_messages', object: @topic %> <%= f.label :title %> <%= f.text_field :title %> <%= f.fields_for :posts do |p| %> <%= p.hidden_field :user_id, :value => current_user.id %> <%= p.label :content %> <%= p.text_area :content %> <% end %> <%= f.submit "Post new topic", class: "button submit" %> <% end %>

应用程序/控制器/ topics_controller.rb

 def create @board = Board.find(params[:board_id]) @topic = @board.topics.build(topic_params.merge({user_id: current_user.id})) debugger if @topic.save flash[:success] = "Topic created" redirect_to @topic else render 'new' end end private def topic_params params.require(:topic).permit(:title, posts_attributes: [:content, :user_id]) end