2

I am trying to make a relationship between a user and a shipment model. Am using [devise][1] for generating users everything gone good but now am stopped at this. I am getting This error:

undefined method `first_name' for nil:NilClass

My models

Shipment.rb

class Shipment < ActiveRecord::Base
  belongs_to :user
end

User.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

My controllers

Shipments_Controller.rb

class ShipmentsController < ApplicationController
  before_action :set_shipment, only: [:show, :edit, :update, :destroy]

  # GET /shipments
  # GET /shipments.json
  def index
    @shipments = Shipment.all
  end

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

  # GET /shipments/new
  def new
    @shipment = Shipment.new
  end

  # GET /shipments/1/edit
  def edit
  end

  # POST /shipments
  # POST /shipments.json
  def create
    @shipment = Shipment.new(shipment_params)

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

  # PATCH/PUT /shipments/1
  # PATCH/PUT /shipments/1.json
  def update
    respond_to do |format|
      if @shipment.update(shipment_params)
        format.html { redirect_to @shipment, notice: 'Shipment was successfully updated.' }
        format.json { render :show, status: :ok, location: @shipment }
      else
        format.html { render :edit }
        format.json { render json: @shipment.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /shipments/1
  # DELETE /shipments/1.json
  def destroy
    @shipment.destroy
    respond_to do |format|
      format.html { redirect_to shipments_url, notice: 'Shipment was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_shipment
      @shipment = Shipment.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def shipment_params
      params.require(:shipment).permit(:user_id, :description, :from, :to, :date, :pay)
    end
end

My db Migration files are:

devise_create_users.rb

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|

      t.string :first_name
      t.string :last_name
      t.string :city_name

      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end



add_user_id_to_shipment.rb
class AddUserIdToShipments < ActiveRecord::Migration
  def change
    add_column :shipments, :user_id, :integer
    add_index :shipments, :user_id
    remove_column :shipments, :name
  end
end

My Shipment Views files:

_form.html.erb

<%= simple_form_for(@shipment, html: {class: "form-horizontal"}) do |f| %>
  <% if @shipment.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@shipment.errors.count, "error") %> prohibited this shipment from being saved:</h2>

      <ul>
      <% @shipment.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <%= f.input :user_id %>
  <%= f.input :description %>

  <div class="field">
    <%= f.label :ship_from %><br>
    <%= f.select :from, ['New York']%>
  </div>

  <div class="field">
    <%= f.label :ship_to %><br>
        <%= f.select :to, [ 'New york', 'Orlanda' ] %>
  </div>
    <%= f.input :date %>
    <%= f.input :pay %>
  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

Index.html.erb

<div class="page-header">
<h1>Listing Shipments</h1>
</div>

<%= link_to "Post a new Shipment", new_shipment_path, class: "btn btn-success" %>

<% @shipments.each do |shipment| %>
<div class="shipment">
  <h3><strong><%= shipment.user.first_name %></strong></h3>
  <h5><strong>DESCRIPTION: </strong><%= shipment.description %></h5>
  <div class="meta">
    <%= link_to time_ago_in_words(shipment.created_at) + " ago" %> |
    <%= link_to "show", shipment %>
    <span class="admin"> 
        | <%= link_to "Edit", edit_shipment_path(shipment) %> |
        <%= link_to "Delete", shipment, method: :delete, data: { confirm: "Are you sure?"} %>
  </span>
    </div>
  </div>
  <% end %>

Show.html.erb <%= notice %>

<p>
  <strong>Name:</strong>
  <%= @shipment.user.first_name %>
</p>

<p>
  <strong>Shipment Description:</strong>
  <%= @shipment.description %>
</p>

<p>
  <strong>Shipment From:</strong>
  <%= @shipment.from %>
</p>

<p>
  <strong>Ship To:</strong>
  <%= @shipment.to %>
</p>

<p>
  <strong>Shipment Date:</strong>
  <%= @shipment.date %>
</p>

<p>
  <strong>Pay:</strong>
  <%= @shipment.pay %>
</p>

<%= link_to 'Edit', edit_shipment_path(@shipment) %> |
<%= link_to 'Back', shipments_path %>

My command line show this log:

Started GET "/" for ::1 at 2015-07-28 16:07:24 +0530
Processing by ShipmentsController#index as HTML
  Shipment Load (0.0ms)  SELECT "shipments".* FROM "shipments"
  User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT
 1  [["id", 1]]
  Rendered shipments/index.html.erb within layouts/application (0.0ms)
Completed 500 Internal Server Error in 16ms (ActiveRecord: 0.0ms)

ActionView::Template::Error (undefined method `first_name' for nil:NilClass):
     6:
     7: <% @shipments.each do |shipment| %>
     8: <div class="shipment">
     9:   <h3><strong><%= shipment.user.first_name %></strong></h3>
    10:   <h5><strong>DESCRIPTION: </strong><%= shipment.description %></h5>
    11:   <div class="meta">
    12:         <%= link_to time_ago_in_words(shipment.created_at) + " ago" %> |

  app/views/shipments/index.html.erb:9:in `block in _app_views_shipments_index_h
tml_erb__634505161_51269712'
  app/views/shipments/index.html.erb:7:in `_app_views_shipments_index_html_erb__
634505161_51269712'


  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
 (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within
 rescues/layout (31.2ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/_markup.html.erb (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inline
d_string (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_s
tring (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/console.js.erb within layouts/javascript (31.2ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/main.js.erb within layouts/javascript (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.0ms)
  Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/index.html.erb (78.0ms)
Ahmed Reza
  • 293
  • 1
  • 3
  • 19

1 Answers1

0

It looks like a particular shipment has no user associated to it. For a quick fix, try the below code

<h3><strong><%= shipment.try(:user).try(:first_name) %></strong></h3>
Pavan
  • 33,316
  • 7
  • 50
  • 76
  • Yeah the same one sir i had put the lines you given in my index.html.erb of views @pavan – Ahmed Reza Jul 28 '15 at 11:17
  • 1
    @Denialsmith `Try this <%= shipment.try(:user).try(:first_name) %>` – Pavan Jul 28 '15 at 11:22
  • now i am not getting any error but the problem remains am not getting first name out there as result. – Ahmed Reza Jul 31 '15 at 13:32
  • @Denialsmith Yes. That's the problem. One of the particular shipment has no associated user. So it returns nil always. You have to look into the DB and assign some existing user_id to shipment whose user_id is nil and check. – Pavan Jul 31 '15 at 13:37