开发者

How to create nested objects in Rails3 using accepts_nested_attributes_for?

I cannot figure out how I can setup a form that will create a new Study while also creating the related StudySubject and the Facility. The user_id, facility_id and study_subject_id have to be available to create the Study object as you can see in the database relation model.

How to create nested objects in Rails3 using accepts_nested_attributes_for?

Here is the migration for the studi开发者_JAVA技巧es. The other tables do not contain foreign keys.

def self.up
 create_table :studies do |t|
  t.references :user
  t.references :facility
  t.references :subject
  t.date "from"
  t.date "till"
  t.timestamps
 end
 add_index :studies, ["user_id", "facility_id", "subject_id"], :unique => true
end

The models define the following associations.

# user.rb
has_many :studies

# subject.rb
has_many :studies

# facility.rb
has_many :studies

# study
belongs_to :user
belongs_to :subject
belongs_to :facility

Questions

1) Are the has_many and belongs_to definitions correct?

2) How can I create a study using accepts_nested_attributes_for?

3) A study should only belong to one user. Do I need to add the user_id into every other object to store the association?

I am totally new to Rails since 2 weeks of extensive learning. Sorry for a stupid question maybe.


Yeah. It works. A good friend offered his help. This is what we set up.
Please mind that I renamed StudySubject to Subject in the meantime.

The model study.rb

belongs_to :student, :class_name => "User", :foreign_key => "user_id"  
belongs_to :subject  
belongs_to :university, :class_name => "Facility", :foreign_key => "facility_id"  

accepts_nested_attributes_for :subject, :university

The controller studies_controller.rb

def new
  @study = Study.new
  @study.subject = Subject.new
  @study.university = Facility.new
end

def create
  @study = Study.new(params[:study])
  @study.student = current_user

  if @study.save
    flash[:notice] = "Successfully created study."
    redirect_to(:action => 'index')
  else
    render('new')
  end
end

I use devise for authentication and cancan for authorization. That is why current_user is available in the controller.

The new study view new.html.erb

<%= form_for @study, :url => { :action => "create" } do |f| %>

  <table summary="Study form fields">

    <%= render :partial => "shared/study_form_fields", :locals =>  { :f => f } %>

    <%= f.fields_for :subject do |builder| %>
      <%= render :partial => "shared/subject_form_fields", :locals =>  { :f => builder } %>
    <% end %>

    <%= f.fields_for :university do |builder| %>
      <%= render :partial => "shared/facility_form_fields", :locals =>  { :f => builder } %>
    <% end %>

  </table>

  <p><%= f.submit "Submit" %></p>

<% end %>

I hope this will save you some time. I spent a lot of time to realize how things have to be set up.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜