问题
I two models User
and Submission
as follows:
class User < ActiveRecord::Base
# Associations
has_many :submissions
accepts_nested_attributes_for :submissions
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :name, :role, :submission_ids, :quotation_ids, :submissions_attributes
validates :email, :presence => {:message => "Please enter a valid email address" }
validates :email, :uniqueness => { :case_sensitive => false }
end
class Submission < ActiveRecord::Base
belongs_to :user
attr_accessible :due_date, :text, :title, :word_count, :work_type, :rush, :user, :notes
validates :work_type, :title, :text,:presence => true
validates :text, :length => { :minimum => 250 }
validates :word_count, :numericality => { :only_integer => true }
end
I have a form which collects the data required by these two models. Users controller:
def index
@user = User.new
@user.submissions.build
end
def create
@user = User.where(:email => params[:user][:email]).first_or_create(params[:user])
if @user
redirect_to :root
else
render 'pages/index'
end
end
What I want to do is first check if the user already exists in the system by the email submitted. If so then I want to create a submission for that user. Otherwise create the user and submission at the same time.
I'm confused on how to do this with the first_or_create
method.
Any help appreciated.
回答1:
first_or_create
accepts a block. So you could do it as follows:
@user = User.where(:email => params[:user][:email]).first_or_create do |user|
# This block is called with a new user object with only :email set
# Customize this object to your will
user.attributes = params[:user]
# After this, first_or_create will call user.create, so you don't have to
end
回答2:
Since your use case is a little more complicated, it may not hurt to split this up into two separate actions. If you want this to occur atomically, you can throw it in a transaction.
User.transaction do
# Create the user if they don't already exist
@user = User.where(:email => params[:user][:email]).first_or_create
# Update with more attributes, and create nested submissions
@user.update_attributes(params[:user])
end
回答3:
Hey I think it should be something like that
@user = User.first_or_create(params[:user])
Then in user model
def first_or_create(params)
unless user = User.where(:email => params[:email]).first # try to find user
user = User.create(email: params[:user])
# it should create also submission because of accepts_nested_attributes_for
else #user exsists so we need to create submission for him
user.submissions.create(params[:submissions])
end
end
来源:https://stackoverflow.com/questions/16644756/first-or-create-by-email-and-then-save-the-nested-model