RAILS: undefined method `profile' for nil:NilClass in nested models and callbacks
===

This is an actual working example, which i have broken down and simplified on the request from two members in previous post containing more details.  These codes I have extracted and rewritten to solve persistent problem: undefined method "profile" for nil:NilChass for nearly two days.  

I use gem "faker", and SQLite Database Browser omitting controller and views and focusing on modelling issue.

The original problem arose in Goal.rb with the error message stating: "undefined method `profile' for nil:NilClass".  According to SQLite DB Browser, user and profile records have successfully created.

The problem lies a line "user.profile.lbm_lbs" under Goal.rb model.  I do not quite understand why user.profile does not exist even though user.profile has been created via admin.profile = Profile.create!(name...) sample_data.rake  (gem faker) appling bundle exec rake db:populate

The previous link I posted: 
http://stackoverflow.com/questions/11381027/rails-how-to-make-new-collection-build-in-a-callback


    BffmModel::Application.routes.draw do
      resources :users do
        resource :profile
        resource :goal
        resource :tdee
        resources :progress_charts
      end
    end
    
    # == Schema Information
    #
    # Table name: users
    #
    #  id              :integer         not null, primary key
    #  email           :string(255)
    #  password_digest :string(255)
    #  created_at      :datetime        not null
    #  updated_at      :datetime        not null
    #  remember_token  :string(255)
    #
    
    class User < ActiveRecord::Base
        attr_accessible :email, :email_confirmation, :password, :password_confirmation
    
    	has_secure_password
    	has_one :profile
    	has_one :goal
    	has_one :tdee
    	has_many :progress_charts
    
    	before_save { |user| user.email = email.downcase }
    	before_save :create_remember_token
    
    	VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    
    	validates :email, :confirmation => true, :presence => true, 
    						length: { maximum: 50 },
    						format: { with: VALID_EMAIL_REGEX },
    						uniqueness: { case_sensitive: false }
    
    	validates :email_confirmation, :presence => true
    	validates :password, length: { minimum: 6 }
    	validates :password_confirmation, presence: true
    
    	private
    
        	def create_remember_token
          		self.remember_token = SecureRandom.urlsafe_base64
        	end
    end
    
    # == Schema Information
    #
    # Table name: profiles
    #
    #  id               :integer         not null, primary key
    #  name             :string(255)
    #  surname          :string(255)
    #  gender           :string(255)
    #  date_of_birth    :date
    #  body_weight_lbs  :integer
    #  height_in_feets  :integer
    #  height_in_inches :integer
    #  bf_pct           :decimal(5, 2)
    #  bf_lbs           :decimal(5, 2)
    #  lbm_lbs          :decimal(5, 2)
    #  user_id          :integer
    #  created_at       :datetime        not null
    #  updated_at       :datetime        not null
    #
    
    class Profile < ActiveRecord::Base
    	attr_accessible	:name, :surname, :gender, :date_of_birth, :body_weight_lbs,
      					:bf_pct, :height_in_feets, :height_in_inches
      	belongs_to :user
    
    	before_save :set_gender
    	before_save :calculate_body_fat_lbs
    	before_save :calculate_lean_body_mass_lbs
    
    	private
    
    		def set_gender
    			if self.gender == "1"
    				self.gender = "Male"
    			elsif self.gender == "2"
    				self.gender = "Female"
    			end
    		end
    
    		def calculate_body_fat_lbs
    			self.bf_lbs = ( self.bf_pct / 100 ) * self.body_weight_lbs
    			self.bf_lbs = self.bf_lbs.round(0)
    		end
    
    		def calculate_lean_body_mass_lbs
    			self.lbm_lbs = self.body_weight_lbs - self.bf_lbs
    		end
    end
    
    # == Schema Information
    #
    # Table name: goals
    #
    #  id                    :integer         not null, primary key
    #  desired_bf_pct        :decimal(, )
    #  goal_type             :string(255)
    #  ideal_body_weight_lbs :decimal(5, 2)
    #  ideal_bfm_lbs         :decimal(5, 2)
    #  fat_to_lose_lbs       :decimal(5, 2)
    #  lbm_to_gain_lbs       :decimal(5, 2)
    #  user_id               :integer
    #  created_at            :datetime        not null
    #  updated_at            :datetime        not null
    #
    
    class Goal < ActiveRecord::Base
      attr_accessible :desired_bf_pct, :goal_type
    
      belongs_to :user
    
      before_save :set_goal
      before_save :calculate_ideal_body_weight_lbs
    	
      private
    
        def set_goal
          if self.goal_type == "1"
            self.goal_type = "Lose Fat"
          elsif self.goal_type == "2"
            self.goal_type = "Gain Muscles"
          end
        end
    
        def calculate_ideal_body_weight_lbs
          
       	  self.ideal_body_weight_lbs = user.profile.lbm_lbs / ( 1 - ( self.desired_bf_pct / 100 ) )
          self.ideal_body_weight_lbs = self.ideal_body_weight_lbs.round(0)
        end
    end

/lib/tasks/sample_data.rake as a testing data
    
    namespace :db do
      desc "Fill database with sample data"
      task populate: :environment do
        admin = User.create!(email: "mikey@example.com",
                             email_confirmation: "mikey@example.com",
                             password: "foobar",
                             password_confirmation: "foobar")
    
        admin.profile = Profile.create!(name: "Michael",
                                        surname: "Colins",
                                        gender: "Male",
                                        date_of_birth: "1975-03-05",
                                        body_weight_lbs: 200,
                                        bf_pct: 25.5,
                                        height_in_feets: 5,
                                        height_in_inches: 11 )
    
        admin.goal = Goal.create!(  desired_bf_pct: 12,
                                    goal_type: "Lose Fat")
    
        admin.tdee = Tdee.create!( tdee_calc_type: "Harris-Benedict",
                      activity_lvl: "BMR x 1.2")
      end
    end

Thank you.