Gray Spectrum
Gray Spectrum

Reputation: 733

Why isn't my join working?

A user has one profile. A profile belongs to a user. The query seems to be working in postgres, but I'm failing at getting the associations to work properly in the view. Here are the query results:

  User Load (0.4ms)  SELECT "users".* FROM "users"   ORDER BY "users"."id" ASC
  User Load (0.3ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 5 ORDER BY "users"."id" ASC LIMIT 1
  Profile Load (0.3ms)  SELECT  "profiles".* FROM "profiles"  WHERE "profiles"."user_id" = $1 LIMIT 1  [["user_id", 5]]

Here are the two models of user and profile:

User:

class User < ActiveRecord::Base

   devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :confirmable

   has_one :profile, dependent: :destroy

   accepts_nested_attributes_for :profile, allow_destroy: true

end

Profile:

class Profile < ActiveRecord::Base

   belongs_to :user, polymorphic: true

end

The controllers...

User:

class UsersController < ApplicationController

   def index
      @profiles = Profile.all
      @users = User.all.order(:id)
      User.joins(:profile)
   end

   private
      def set_user
         @user = User.find(params[:id])
      end

 end

Profile:

class ProfilesController < ApplicationController
   before_action :set_profile, only: [:show, :edit, :update, :destroy]

   # GET /profiles
   # GET /profiles.json
   def index
      @profiles = Profile.all
   end

   # GET /profiles/1
   # GET /profiles/1.json
   def show
   end

   # GET /profiles/new
   def new
      @profile = Profile.new
   end

   # POST /profiles
   # POST /profiles.json
   def create
      @profile = Profile.new(profile_params)

      respond_to do |format|
         if @profile.save
            format.html { redirect_to @profile, notice: 'Profile was successfully created.' }
            format.json { render :show, status: :created, location: @profile }
         else
            format.html { render :new }
            format.json { render json: @profile.errors, status: :unprocessable_entity }
         end
      end
   end

 private

   def set_profile
      @profile = Profile.find(params[:id])
   end

   def profile_params
      params.require(:profile).permit(:user_id)
   end

end

Finally in the /users/index view:

<%= user.profile.user_id %>

But when I try to render the view, I receive the following error:

undefined method `user_id' for nil:NilClass

I appreciate any help.

Upvotes: 0

Views: 58

Answers (1)

Nermin
Nermin

Reputation: 6100

If you do not really need association to be polymorphic, you then should remove it from Profile model.

class Profile < ActiveRecord::Base

   belongs_to :user
end

But if you do need the association to be polymorphic, then you need to change User model.

class User < ActiveRecord::Base

   devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :confirmable

   has_one :profile,
      dependent: :destroy,
      as: user

   accepts_nested_attributes_for :profile, allow_destroy: true

end

and also you need to add user_type in your Profile model

Upvotes: 1

Related Questions