对于在Rails中具有多个关联的嵌套资源,“创建”操作

时间:2014-05-10 20:00:53

标签: ruby-on-rails activerecord model-associations nested-resources

我有item个,每个都有多个(线程)comment s 线程通过parent键完成,该键指向另一个comment

我无法让create操作正常工作,我已经足够提交到数据库,但它没有item_id和{{1设置。

我尝试parent_id代替form_for [@item, @comment],但它也没有帮助。

当我在form_for :comment, url: item_comments_path( @item )行动中查看comment_params时,我得到了这个:

create

有人可以帮忙吗?

模型:

Parameters: {"utf8"=>"✓", "comment"=>{"body"=>"examplecommentgoeshere"}, "parent_id"=>"4", "commit"=>"Create Comment", "item_id"=>"4"}

评论控制器:

class Item < ActiveRecord::Base
  belongs_to :user
  has_many :comments, dependent: :destroy
  has_many :images,   as: :item,
                      dependent: :destroy

  validates :title,       presence: true,
                          allow_blank: false
  validates :description, presence: true,
                          allow_blank: false
  validates :user,        presence: true,
                          allow_blank: false
  validates :layout,        presence: true
end


class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :item
  has_many :responses,  class_name: "Comment",
                        foreign_key: "parent_id",
                        dependent: :destroy
  has_one :image,       as: :item,
                        dependent: :destroy
  belongs_to :parent,   class_name: "Comment"

  validates :body,      presence: true,
                        allow_blank: false,
                        length: { minimum: 10 }
end

项目视图:

class CommentsController < ApplicationController
  before_filter :findParent
  before_filter :find, only: [:update, :destroy, :show]
  before_filter :is_logged_in?, only: [:create, :update, :destroy]
  before_filter :has_permission?, only: [:update, :destroy]

  def new
    @comment = Comment.new
  end

  def create
    logger.debug comment_params.inspect
    @comment = current_user.comments.build(comment_params)

    if @comment.save
      redirect_to @item
    else
      logger.debug @comment.errors.inspect
      session[:errorbj] = @comment
      redirect_to @item
    end
  end
  [...]
  private
  def comment_params
    params.require(:comment).permit(:body, :parent)
  end

  private
  def find
    @comment = Comment.find(params[:id])
  end

  private
  def findParent
    @item = Item.find params[:item_id]
  end

部分评论/表格:

<p>
<h3>Add a comment:</h3>
  <%= render partial: 'comments/form', locals: { parent: @item } %>
</p>

从另一个stackoverflow线程我得出结论,在多关联中创建对象的唯一方法是执行以下操作:

<%= form_for :comment, url: item_comments_path( @item ) do |f| %>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>

  <p>
    <%= f.label :image %><br>
    &lt;nope&gt;
  </p>

  <%= hidden_field_tag :parent_id, parent.id %>
  <p>
    <%= f.submit %>
  </p>
<% end %>

其他stackoverflow帖子却表示不做

@comment = current_user.comments.build( comment_params.join( { parent_id: <parent.id> } ) )

那么真的没有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

我认为您的代码中存在很多错误。我希望我能把它变成一种可以帮助你自己解决问题的形式:

  • 使用form_for [@item, @comment]
  • findParent应为find_parent
  • findParent应设置@parent
  • findParent应找到Comment
  • new操作应使用父@comment = Comment.new parent: @parent
  • 进行初始化
  • hidden_field_tag :parent_id, parent.id应为form.hidden_field :parent
  • 应通过comment_params
  • 设置父关联
  • 您不需要Rails.logger语句,所有这些都在logs / development.log中
  • 不要将对象放入会话
  • 为什么有itemimage

了解有关调试的更多信息! http://nofail.de/2013/10/debugging-rails-applications-in-development/

答案 1 :(得分:0)

事实证明这比看起来容易得多。

这就是我最终做到的方式:

class CommentsController < ApplicationController
  before_filter :findParent, only: [:create]
  [...]
  def create
    @comment = current_user.comments.build(comment_params)
    @comment.item = @item
    if @comment.save
      redirect_to @item
    else
      session[:errorbj] = @comment
      redirect_to @item
    end
  end