MathRivest
MathRivest

Reputation: 9

Nested form validation rails 3.2

I have a job and user(devise) form in the same view. When I am trying to submit with errors in the user fields it gives me an exception page with the validation messages. Submitting errors in the job fields works fine!

job_controller.rb
def new
  @job = Job.new
  if !current_user
    @job.user = User.new
  end

  respond_to do |format|
    format.html # new.html.erb
  end
end

  def create
    @types = Type.all
    @categories = Category.all

    @job = Job.new(params[:job])
    #if not logged in creates a user and sign in
    if !current_user
      @user = User.new(params[:job][:user_attributes])
    else
      @user = current_user
    end

    @job.user_id = @user.id

    respond_to do |format|
      if @job.save
        if !current_user
          sign_in(:user, @user)
        end
        format.html { redirect_to @job }
      else
        format.html { render action: "new" }
      end
    end
  end

  job.rb
  attr_accessible :user_attributes, :description, :name ....
  belongs_to :user
  accepts_nested_attributes_for :user

Thanks!

Upvotes: 0

Views: 81

Answers (1)

James Daniels
James Daniels

Reputation: 6981

That becuase you are calling, @user.save! which will generate an exception. Also doing it this way won't put the job in the same transaction as User. What you want are nested_attributes:

class Job < ActiveRecord::Base

   accepts_nested_attributes_for :user

end

If the user is logged in, don't show that part of the form and filter those params.

See more in the Rails documentation here http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

EDIT:

Simplify your controller code, since you're using nested attributes you no longer need to manually create a user.

#if not logged in creates a user and sign in
if !current_user
  @user = User.new(params[:job][:user_attributes]) # this is no longer needed
else
  @user = current_user
end

@job.user_id = @user.id # this is redundant

To something more like:

# if logged in, manually assign the user (also you may want to reject any user attributes)
@job.user = current_user if current_user

Upvotes: 1

Related Questions