1

トピックと投稿の2つのリソースがあります。Postコントローラーを使用してトピックを作成する方法を理解しようとしています。モデルは次のようになります。

class Topic < ActiveRecord::Base
  has_many :posts, :dependent => :destroy
  validates :name, :presence => true,
                   :length => { :maximum => 32 }
  attr_accessible  :name
end

class Post < ActiveRecord::Base
  belongs_to :topic,    :touch => true
  has_many   :comments, :dependent => :destroy
  accepts_nested_attributes_for :topic
  attr_accessible :name, :title, :content, :topic
end

posts / _form.html.erb:

<%= simple_form_for @post do |f| %>
  <h1>Create a Post</h1>
  <%= f.input :name, :label => false, :placeholder => "Name" %>
  <%= f.input :title, :label => false, :placeholder => "Title" %>
  <%= f.input :content, :label => false, :placeholder => "Content" %>
  <%= f.input :topic, :label => false, :placeholder => "Topic" %>  
  <%= f.button :submit, "Post" %>  
<% end %>

posts_controller.rb#create:

def create
  @post = Post.new(params[:topic])
  respond_to do |format|
    if @post.save
      format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
    else
      format.html { render :action => "new" }
    end
  end
end

posts / _form.html.erbを使用して投稿を作成できますが、関連するトピックは一緒に作成されません。なぜ私がこの振る舞いをするのか、そしておそらくそれを修正する方法を誰かに教えてもらえますか?Ruby 1.9.2、Rails 3.0.7、simple_formgemを使用しています。

4

3 に答える 3

3

Railscastsには、この問題に関するいくつかのエピソードがあります。エピソード16(サブスクリプションが必要)

ソースコード: https ://github.com/railscasts/016-virtual-attributes-revised

そしてこのエピソード http://railscasts.com/episodes/57-create-model-through-text-field

views / products / _form.rhtml

<p>
<label for="product_category_id">Category:</label><br />
<%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
or create one:
<%= f.text_field :new_category_name %>
</p>

models / product.rb

belongs_to :category
attr_accessor :new_category_name
before_save :create_category_from_name

def create_category_from_name
create_category(:name => new_category_name) unless new_category_name.blank?
end

カテゴリに関するライアンのソリューションは、@nathanvdaのオプション1よりもエレガントだと思います。コントローラーではなくモデルでデータを処理するためです。異なるコントローラー/アクションで同じ作業を行う必要がある場合は、利点がわかります。

于 2012-11-05T03:23:53.013 に答える
2

あなたがやりたいことに応じて、私は2つのオプションを見ることができます。

オプション1:テキストボックスを使用して、既存のトピックを作成または検索します(以前のように)。コントローラでは、次のように記述します。

def create
  topic_name = params[:post].delete(:topic)
  @topic = Topic.find_or_create_by_name(topic_name)
  @post = Post.new(params[:post])
  @post.topic = @topic
  if @post.save
    format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
  else
    format.html { render :action => "new" }
  end
end

それは迅速で汚い方法です。入力するたびtopicに、名前でそのトピックを検索するか、作成して割り当てます。ただし、これはエラーが発生しやすいです。トピックのセットが限られている場合は、はるかに簡単な方法があります。

オプション2:利用可能なトピックのリストである選択ボックスを使用します。あなたの見解では、次のように書いてください。

<%= simple_form_for @post do |f| %>
  <h1>Create a Post</h1>
  <%= f.input :name, :label => false, :placeholder => "Name" %>
  <%= f.input :title, :label => false, :placeholder => "Title" %>
  <%= f.input :content, :label => false, :placeholder => "Content" %>
  <%= f.association :topic %>  
  <%= f.button :submit, "Post" %>  
<% end %>

これにより、可能なトピックを含む選択ボックスがレンダリングされます。そして、あなたのコントローラーであなたはただ書く必要があります:

def create
  @post = Post.new(params[:post])
  if @post.save
    format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
  else
    format.html { render :action => "new" }
  end
end

この2番目のオプションは非常に簡単ですが、その場でトピックを追加するのは簡単ではありません。オートコンプリートフィールドを使用して、その間に何かを行うことができます。これにより、値が存在する場合は値を検索でき、存在しない場合は新しい値を追加できます。

お役に立てれば。

于 2011-05-01T14:38:36.043 に答える
1

サーバーログに一括割り当てエラーが発生していますか?attr_accessibleリストに:topic_attributesを追加する必要がある場合があります。

于 2011-05-01T03:46:07.010 に答える