First_or_create by email and then save the nested model

I two User and Submission models 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 that collects the data required by these two models. User 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 exists in the system by email. If so, I want to create a view for this user. Otherwise, create a user and send it at the same time.

I am confused about how to do this using the first_or_create method.

Any help was appreciated.

+8
ruby ruby-on-rails nested-attributes
source share
3 answers

first_or_create takes a block . Therefore, you can 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 
+13
source share

Since your use case is a little more complicated, it might not hurt to split it into two separate actions. If you want this to happen atomically, you can throw it into 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 
+1
source share

Hey i think it should be something like this

 @user = User.first_or_create(params[:user]) 

Then in custom 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 
-3
source share

All Articles