Associating two records after create in Rails
I'm working on an association between two models:
class Person < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :person
end
Many person
records exist in the system that don't necessarily correspond to a user
, but when creating a user
you need to either create a new person
record or associate to an existing one.
What would be the best way to associate these two models when the person
reco开发者_开发技巧rd already exists? Do I need to manually assign the user_id
field, or is there a Rails way of doing that?
Where @user is a recently created user, and @person is an existing person.
@user.person = @person
@user.save
Alternately:
User.new :person => @person, ... #other attributes
or in params form:
User.new(params[:user].merge({person => @person}))
As far as forms go:
<% form_for @user do |f| %>
...
<% fields_for :person do |p| %>
<%= p.collection_select, :id, Person.all, :id, :name, :include_blank => "Use fields to create a person"%>
<%= p.label_for :name%>
<%= p.text_field :name %>
...
<% end %>
<% end %>
And in the user controller:
def create
@user = User.create(params[:user])
@person = nil
if params[:person][:id]
@person = Person.find(params[:person][:id])
else
@person = Person.create(params[:person])
end
@user.person = @person
...
end
If you don't want to create/alter a form for this, you can do
@person_instance.user = @user_instance
For has_many relationships, it would be:
@person_instance.users << @user_instance
You first have to do a nested form :
<% form_for @user do |user| %>
<%= user.text_field :name %>
<% user.fields_for user.person do |person| %>
<%= person.text_field :name %>
<% end %>
<%= submit_tag %>
<% end %>
In your User model :
class User < ActiveRecord::Base
accepts_nested_attributes_for :person
end
If you want the person deleted when the user is :
class User < ActiveRecord::Base
accepts_nested_attributes_for :person, :allow_destroy => true
end
And in your controller do nothing :
class UserController < ApplicationController
def new
@user = User.new
#find the person you need
@user.person = Person.find(:first)
end
def create
@user = User.new(params[:user])
@user.save ? redirect_to(user_path(@user)) : render(:action => :new)
end
end
精彩评论