ruby-on-rails-3activerecordrails-models

Can't create belongs_to association in controller


I have 2 models Users and Companies. (I'm using Devise for User)

My User model includes an client_id column.

At the moment a User signs-up and is directed to the new_company_path where I'd like to create the relationship. (I'd prefer to keep this in 2 steps).

I know my code is wrong here in the companies_controller.rb — but it's where I'm at

  def create
    @user = current_user
    @company = @user.Company.new(params[:company])

    respond_to do |format|
      if @company.save
        format.html { redirect_to root_path, notice: 'Company was successfully created.' }
        format.json { render json: @company, status: :created, location: @company }
      else
        format.html { render action: "new" }
          format.json { render json: @company.errors, status: :unprocessable_entity }
      end
    end

Solution

  • Your problem lies within the line

    @company = @user.Company.new(params[:company])
    

    The association from user to company should not be accessed with a capital letter. To get the company associated with a user, you should call it like this:

    @user.company
    

    However, if there is no company associated then that method will return nil and you cannot call .new on nil so instead you need to call another method that Rails creates for you called build_company like this:

    @company = @user.build_company(params[:company])
    

    The last problem is that since it is the user that belongs to the company, the User instance needs to be updated with the newly created company_id and that will not happen if you only save the company. But when you use the build_company method, it will store the company instance in the association from User so if you call save on the user instead of the company it will create the company and link it to user, like this:

    def create
      @user = current_user
      @user.build_company(params[:company])
    
      respond_to do |format|
        if @user.save
          format.html { redirect_to root_path, notice: 'Company was successfully created.' }
          format.json { render json: @user.company, status: :created, location: @user.company }
        else
          format.html { render action: "new" }
          format.json { render json: @user.company.errors, status: :unprocessable_entity }
        end
      end
    end