使用accepts_nested_attributes_for我不能创建模型对象。它不会产生嵌套对象 [英] I can't create model objects using accepts_nested_attributes_for. It won't create the nested object

查看:479
本文介绍了使用accepts_nested_attributes_for我不能创建模型对象。它不会产生嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的模型结构如下:

董事会的has_many话题。主题的has_many帖子。

Board has_many Topics. Topic has_many Posts.

应用程序/模型/ 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部分用于创建:在新邮含量

Here is my view for creating a new Topic. the fields_for section is used to create the :content on the new Post

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

<div>
    <%= form_for [@board, @topic] do |f| %>

    <%= render 'shared/error_messages', object: @topic %>

    <%= f.label :title %>
    <%= f.text_field :title %>

    <%= f.fields_for @post do |p| %>
        <%= p.label :content %>
        <%= p.text_area :content %>
    <% end %>

    <%= f.submit "Post new topic", class: "button submit" %>
    <% end %>
</div>

在创建一个新的话题,我希望有一个新的职位的:从形式到内容也被创建。由于邮政是依赖于为了有效具有主题,它们需要创建或串联拒绝(如果:内容或:标题是无效的)。有人告诉我,accepts_nested_attributes_for会正常工作,但是当我的code执行仅仅创建主题,而不是帖子。

When creating a new Topic, I want a new post with the :content from the form to also be created. Since the Post is dependent on having a Topic in order to be valid, they need to be created or rejected in tandem (if the :content or :title is invalid). I was told that accepts_nested_attributes_for would work correctly but when my code executes it only creates the Topic, not the 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

有关记录,这里是我的帖子控制器和路线,如果有帮助。

For the record, here is my Posts controller and routes, if it helps.

应用程序/控制器/ 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

和同样价值的 PARAMS 在topics_controller#开始创建

And also the value of params at the start of topics_controller#create

{UTF8=>✓,authenticity_token=>...,主题=> {标题=>新建标题,后=> {内容= >新内容},提交=>发表新帖,行动=>创造,控制器=>主题,board_id=>1}

{"utf8"=>"✓", "authenticity_token"=>"...", "topic"=>{"title"=>"New Title", "post"=>{"content"=>"New Content"}},"commit"=>"Post new topic", "action"=>"create", "controller"=>"topics", "board_id"=>"1"}

推荐答案

终于找到了解决办法<一href=\"http://stackoverflow.com/questions/935650/accepts-nested-attributes-for-child-association-validation-failing\"标题=点击这里>这里

这是在我的固定形式正确地创建PARAMS。

This was after I fixed the form to create the params correctly.

基本上,我需要使用:inverse_of 在我的模型。我真的不明白这是什么来完成,但它的工作原理。这里是我的code

Basically, I needed to use :inverse_of on my models. I don't really understand what this accomplishes but it works. Here's my code

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

<div>
  <%= 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| %>
      <!-- I needed to pass in the current_user.id for the post -->
      <%= 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 %>
</div>

应用程序/控制器/ 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

这篇关于使用accepts_nested_attributes_for我不能创建模型对象。它不会产生嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆