レールは初めてで、これはしばらくの間私を悩ませてきました。ポリモーフィックな関連付けに関するすべてのチュートリアルは、2つのレベルにすぎないようであり、ポリモーフィックモデルにネストされたポリモーフィックモデルはありません。これについては本当に助けが必要です。
投稿、コメント、リンクのモデルがあるアプリがあります。コメントとリンクの両方に多形性があります。Facebookの動作と同様に、コメントと投稿の両方にリンクURLを追加したいだけでなく、他のものへのコメントも追加したいからです。リンクモデルをネストして、1つのフォームとして送信できるようにします。投稿とリンクは機能しますが、コメントとリンクにはMassAssignmentSecurityエラーがあります。
Erorr
ActiveModel::MassAssignmentSecurity::Error in CommentsController#create
Can't mass-assign protected attributes: link
リクエストパラメータ:
{"utf8"=>"✓",
"authenticity_token"=>"
J1JfIINrtvax77M3JcbDDWvHFpyGG1ciK1DisGOLu6M=",
"comment"=>{"content"=>"z",
"link"=>{"link_url"=>"z"}},
"commit"=>"Add comment",
"forum_post_id"=>"16"}
ルート
resources :forum_posts do
resources :comments
resources :links
end
resources :comments do
resources :links
end
Forum_Postモデル
class ForumPost < ActiveRecord::Base
attr_accessible :content, :links_attributes, :comments_attributes , :link_url
has_many :links, :as => :linkable
has_many :comments, :as => :commentable
accepts_nested_attributes_for :links, :allow_destroy => true #, :reject_if => lambda { |t| t[:link].nil?}
end
コメントモデル
class Comment < ActiveRecord::Base
attr_accessible :commentable_id, :commentable_type, :content,:links_attributes, :link_url
belongs_to :commentable, :polymorphic => true
has_many :links, :as => :linkable
accepts_nested_attributes_for :links, :allow_destroy => true #, :reject_if => lambda { |t| t[:link].nil?}
end
リンクモデル
class Link < ActiveRecord::Base
attr_accessible :description, :image_url, :link_url, :linkable_id, :linkable_type, :title, :link_id
belongs_to :linkable, :polymorphic => true
end
Forum_Postコントローラー
class ForumPostsController < ApplicationController
...............
def new
@forum_post = ForumPost.new
@link = @forum_post.links.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: @forum_post }
end
end
........
end
コメントコントローラー
class CommentsController < ApplicationController
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def index
@commentable = find_commentable
@comments = @commentable.comments
end
def create
@commentable = find_commentable
@comment = @commentable.comments.build(params[:comment])
@comment.links.build
if @comment.save
flash[:notice] = "Successfully saved comment."
redirect_to :id => nil
else
render :action => 'new'
end
end
end
リンクコントローラー
class LinksController < ApplicationController
def find_linkable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def index
@linkable = find_linkable
@links = @linkable.links
end
def create
@linkable = find_linkable
@link = @linkable.link.build(params[:link])
if @link.save
flash[:notice] = "Successfully saved link."
redirect_to :id => nil
else
render :action => 'new'
end
end
end
コメント部分表示
<h2>Comments</h2>
<% if commentable.comments.empty? %>
No comments to display.
<% else %>
<% for comment in commentable.comments %>
<%= comment.content %>
<% end %>
<% end %>
<% :link_url %>
<h2>New Comment</h2>
<%= form_for [@commentable, Comment.new] do |f| %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content, :rows => 5 %>
</div>
<%= f.fields_for [@linkable, Link.new] do |link| %>
<%= render :partial => 'links/link', :locals => { :f => link } %>
<% end%>
<div class="actions">
<%= submit_tag "Add comment" %>
</div>
<% end %>
リンク部分表示
<h2>Link Previews</h2>
<div class="field">
<%= f.label :link_url %><br />
<%= f.text_field :link_url, :id => "url_field" %>
</div>