【问题标题】:Refactoring Form_for Create Method for Comments in a Polymorphic Association重构 Form_for 创建多态关联中注释的方法
【发布时间】:2012-04-11 21:04:17
【问题描述】:

我正在处理我的第一个多态关联关系,但在重构我的 form_for create cmets 时遇到问题。

我尝试通过多态协会 RailsCasts http://railscasts.com/episodes/154-polymorphic-association?view=asciicast,但它似乎过时了。

我有两个问题:

  1. 如何重写我的 comment_form 部分,以便它适用于任何可评论的内容?按照我现在的方式,它只适用于自 (:commentable_id => @traveldeal.id) 以来的 traveldeals。

  2. 当我创建评论时,commentable_type 为空。什么是commentable_type,我需要在表单中传递它吗?

谢谢!

用户.rb

class User < ActiveRecord::Base
  has_many :comments, :dependent => :destroy
end

traveldeal.rb

class Traveldeal < ActiveRecord::Base
  has_many :comments, :as => :commentable, :dependent => :destroy
end

comment.rb

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :commentable, :polymorphic => true

  validates :user_id, :presence => true
  validates :commentable_id, :presence => true
  validates :content, :presence => true
end

traveldeal_show.html.erb

<%= render 'shared/comment_form'  %>

_comment_form.html.erb

<%= form_for current_user.comments.build(:commentable_id => @traveldeal.id) do |f| %>
  <%= render 'shared/error_messages', :object => f.object %>

<div>
  <%= f.text_area :content %>
</div>

<%= f.hidden_field :user_id %>
<%= f.hidden_field :commentable_id %>

<div>
  <%= f.submit "Add Comment" %>
</div>
<% end %>

cmets_controller.rb

class CommentsController < ApplicationController
  before_filter :authenticate, :only => [:create, :destroy]

  def create
    @comment = Comment.new(params[:comment])
    @comment.save
    redirect_to root_path
  end

end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 polymorphic-associations


    【解决方案1】:

    Railscast 中唯一注明日期的部分是路线。

    回答您的第一个问题:像在 Railscast 中一样创建表单:

    <%= form_for [@commentable, Comment.new] do |f| %>
      <p>
        <%= f.label :content %><br />
        <%= f.text_area :content %>
      </p>
      <p><%= f.submit "Submit" %></p>
    <% end %>
    

    如果您这样做,commentable_type 将自动设置。您需要类型,以便知道评论属于哪个模型。请注意,您必须在使用评论表单的方法中设置@commentable

    例如

    class TraveldealsController < ApplicationController
      def show
        @traveldeal = @commentable = Traveldeal.find(params[:id])
      end
    end
    

    【讨论】:

    • 感谢您帮我解决这个问题,Mischa。如您的回答所示,我未能为显示页面设置@commentable。
    • 参数 [@commentable, Comment.new] 在做什么?我不太确定Comment.new 在这种情况下的含义。它只是创建一个类似于您在控制器中看到的新记录吗?
    • 因为您有一个嵌套路由,所以您的form_for 需要两个对象。第一个是评论所属的对象(@commentable),第二个是新的评论对象(Comment.new)。所以是的,这就像在控制器中创建新记录一样。您可以在控制器中执行@comment = Comment.new,但您必须在任何有评论表单的地方执行此操作。在视图中只做Comment.new 会更干净。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    相关资源
    最近更新 更多