Dylan Richards
Dylan Richards

Reputation: 708

Devise: current_user == nil?

My goal is to display the 'edit' and 'delete' buttons only to the user who created the listing. However, for some reason, current_user is returning nil. Any idea why this is happening?

Here is my user model:

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

Here is my listing model:

class Listing < ActiveRecord::Base
  belongs_to :user
  has_many :thoughts
end

<% @listings.each do |listing| %>
      <tr>
        <td><%= listing.title %></td>
        <td><%= listing.school %></td>
        <td><%= listing.price %></td>
        <td><%= listing.description %></td>
        <% if current_user == listing.user %>
        <td><%= link_to 'Show', listing %></td>
        <td><%= link_to 'Edit', edit_listing_path(listing) %></td>
        <td><%= link_to 'Delete', listing, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        <% else %>
        <td><%= link_to 'Show', listing %></td>
        <% end %>
      </tr>
    <% end %>

Here is the create action in the Listing controller

def create
  @listing = Listing.new(listing_params)

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

Here is my create_listings migration

class CreateListings < ActiveRecord::Migration
  def change
    create_table :listings do |t|
      t.string :title
      t.string :school
      t.integer :price
      t.text :description

      t.timestamps
    end
  end
end

Upvotes: 0

Views: 5713

Answers (2)

Matt
Matt

Reputation: 14048

Make sure you have before_filter :authenticate_user! set in your controller:

class ListingsController < ActionController::base
  before_filter :authenticate_user!

  def index
    @listings = Listing.all
  end
end

As for your create method, so long as the table has a user_id column you just need to set the user for that listing:

def create
  @listing = Listing.new(listing_params)
  @listing.user = current_user

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

Lastly, for the listing to belong to a user it needs to be able to record that users id. Make sure your table has a user_id column:

class CreateListings < ActiveRecord::Migration
  def change
    create_table :listings do |t|
      t.string :title
      t.string :school
      t.integer :price
      t.text :description
      t.integer :user_id

      t.timestamps
    end
  end
end

You can re-run this migrate if it is your latest by calling rake db:migrate:redo from the console. If it isn't the latest you need to run the down and up specifically with VERSION=xxx to for that migrates ID (follow the steps here: 4.3 Running Specific Migrations). THIS WILL EMPTY THE TABLE. If you need to keep date in that table then you need to write a new migrate with just the command add_column :listings, :user_id, :integer.

Upvotes: 6

NM Pennypacker
NM Pennypacker

Reputation: 6952

I'd do something likesigned_in? && current_user.id == listing.user_id

Upvotes: 0

Related Questions