0

Rails3フォームとネストされたモデルを「機能」させようとしている人々がここにいくつかの異なる投稿があることを私は知っています。Subclass Is n't Saving、 Nested Model with Polymorphic Association、RyanBatesのNestedModelFormsでのRailscastsと彼のComplexFormsに関する2つのチュートリアルを見ながら、それらをたくさん見てきました。

そうは言っても、フォーム内のオブジェクトが保存されない理由については困惑しています。

これが私のモデルです:

course.rb

class Course < ActiveRecord::Base
  attr_accessible :course_name, :course_semester, :course_summary, :course_year, :objectives_attributes

  has_many :objectives, as: :objectiveable
  accepts_nested_attributes_for :objectives, :reject_if => lambda { |a| a[:objective].blank? }, :allow_destroy => true

Objective.rb

class Objective < ActiveRecord::Base
attr_accessible :objective
belongs_to :objectiveable, polymorphic: true

私のフォーム:

new.html.erb

<%= form_for [current_user, @course] do |course| %>

<%= course.label "Course Name" %>
<%= course.text_field :course_name, id:"course_name" %>

<%= course.label "Semester" %>
<%= course.select(:course_semester,[['Fall', 'Fall'], ['Spring', 'Spring'], ['Summer', 'Summer'], ['Winter','Winter']] ) %>

<%= course.label "Course Year" %>
<%= course.text_field :course_year, id:"course_year" %>

<p>Course Objectives</p>
<%= course.fields_for :objectives do |objective| %>

    <%= objective.text_field :objective, name: "objective" %>

<% end %>

<%= course.label "Course Summary" %>
<%= course.text_area :course_summary, id:"course_summary" %>

<%= course.submit "Save and Return", name: "save_and_return" %>
<%= course.submit "Create a Unit", name: "course_to_unit" %>

<% end %>

私のコントローラー:

Courses_controller.rb

class CoursesController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource

def new
  @course = current_user.courses.new
  @course.objectives.build
end

def create
  @course = current_user.courses.new(params[:course])
  if @course.save && params[:save_and_return]
    redirect_to user_path(current_user)
  elsif @course.save && params[:course_to_unit]
    redirect_to new_course_unit_path(@course)
  else
    flash[:notice] = "Sorry, there was a mistake with the form"
    render 'new'
  end
end

私のログ:

test.log

Started POST "/users/1/courses" for 127.0.0.1 at 2012-11-27 22:23:00 -0500
Processing by CoursesController#create as HTML
  Parameters: {"utf8"=>"✓", "course"=>{"course_name"=>"Physics 1", "course_semester"=>"Fall", "course_year"=>"2012", "course_summary"=>"This is a valid course summary."}, "objective"=>"An objective", "save_and_return"=>"Save and Return", "user_id"=>"1"}
  [1m[36mUser Load (0.2ms)[0m  [1mSELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1[0m
  [1m[35m (0.0ms)[0m  begin transaction
  [1m[36mSQL (0.7ms)[0m  [1mINSERT INTO "courses" ("course_name", "course_semester", "course_summary", "course_year", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?)[0m  [["course_name", "Physics 1"], ["course_semester", "Fall"], ["course_summary", "This is a valid course summary."], ["course_year", 2012], ["created_at", Wed, 28 Nov 2012 03:23:00 UTC +00:00], ["updated_at", Wed, 28 Nov 2012 03:23:00 UTC +00:00], ["user_id", 1]]
  [1m[35m (6.1ms)[0m  commit transaction
Redirected to http://www.example.com/users/1
Completed 302 Found in 17ms (ActiveRecord: 7.0ms)

ログのパラメーターハッシュで目的を確認できますが、データがコミットされているときに目的テーブルに何も挿入されていません。私のコンソールでは、@course.objectives.createまたは@course.objectives.buildを使用して目標を作成できるため、関連付けが機能していることがわかります(さらに、Rspecでモデルをテストしました)。しかし、フォームレベルでは、ここで何が間違っているのか理解できません。

また、これをRspecのテストとして実行していることにも注意してください。これは、次のようになります。

course_pages_spec.rb

      it "Adds at least one objective to the course" do
        expect {
          fill_out_course_form_with_valid_info
          click_button save_button
        }.to change(Course, :count).by_at_least(1)
        Course.last.objectives.count.should == 1
      end

Rails Serverも起動しましたが、フォームに値を入力しても同じ結果が得られます。

よろしくお願いします。

4

1 に答える 1

0

ですから、答えは思ったよりずっと簡単でした。ネストされたフォームには、次のものがあります。

<p>Course Objectives</p>
<%= course.fields_for :objectives do |objective| %>

  <%= objective.text_field :objective, name: "objective" %>

<% end %>

「name」を「objective」として定義することにより、デフォルトの「name」、「course [objectives_attributes] [0] [objective]」を上書きしていたことがわかりました。これは、パラメーターが渡される場所/方法です。

Rails Docsによると、

フォームヘルパーは、バニラHTMLを使用する場合に比べて、リソースの操作をはるかに簡単にするように設計されています。

モデルのフォームはform_forで作成されます。このメソッドは、フォームのモデルを認識しているフォームビルダーを生成します。したがって、フォームビルダーは、モデル属性に対応する入力フィールドのデフォルト値、および便利な名前、ID、エンドポイントなどを生成できます。

生成されたフィールド名の規則により、コントローラーは、ユーザーの手間をかけずに、パラメーターで適切に構造化されたフォームデータを受信できます。

そもそも「name」属性を持っていたのは、テストでカピバラに何かをつかむためでした。それはそんなに良い考えではなかったと思います:-)

(代わりに、Firebugを使用してフォームフィールドのIDを把握し、それに対してテストしました。)

于 2012-11-28T04:46:37.623 に答える