I Have a Listings Controller
(Devise User System) and in Rails 3 i just used
before_filter :authenticate_user!, except: [:index]
to check if a user was signed in before viewing a specific listing.
My Homepage (Index) shows at the bottom a view Listings, the User is able to see them, but as soon as he clicks on one to view it he is redirected to the Login Page.
That's why in my controller i had instead of
Listing.new -> current_user.listings.new
In Rails 4 things seems to have changed and i cant find the right way to do it.
I searched a little bit and found that the command was changed to
before_action :authenticate_user!, :except => [:index]
A Guest can view now the Index but if he clicks on a Listing, he is not redirected to the login page, instead i get this error.
NoMethodError in ListingsController#show
undefined method `listings' for nil:NilClass
# Use callbacks to share common setup or constraints between actions.
def set_listing
@listing = current_user.listings.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
My Listings Controller
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, :except => [:index]
# GET /listings
# GET /listings.json
def index
@listings = Listing.order("created_at desc")
end
# GET /listings/1
# GET /listings/1.json
def show
end
# GET /listings/new
def new
@listing = current_user.listings.build
end
# GET /listings/1/edit
def edit
end
# POST /listings
# POST /listings.json
def create
@listing = current_user.listings.build(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
# PATCH/PUT /listings/1
# PATCH/PUT /listings/1.json
def update
respond_to do |format|
if @listing.update(listing_params)
format.html { redirect_to @listing, notice: 'Listing was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @listing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
@listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
@listing = current_user.listings.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:title, :description, :image)
end
end
EDIT: PROBLEM 2
If another Logged in User tries to view a listing which another User created im getting this ->
and the log
Try this, this will allow guests to see listing supplied in the parameter:
def set_listing
unless current_user
@listing = Listing.find(params[:id])
else
@listing = current_user.listings.find(params[:id])
end
end
Update:
It appears that you want to display listings by parameter and not by the current_user
. If so then please update your set_listing
definition as follows:
def set_listing
@listing = Listing.find(params[:id]) if params[:id]
end