web-dev-qa-db-fra.com

before_filter: authenticate_user !, sauf: [: index] / Rails 4

J'ai un Listings Controller (Devise User System) et dans Rails je viens d'utiliser

before_filter :authenticate_user!, except: [:index]

pour vérifier si un utilisateur était connecté avant d'afficher une liste spécifique.

Ma page d'accueil (index) montre en bas une vue des listes, l'utilisateur peut les voir, mais dès qu'il clique sur une pour la voir, il est redirigé vers la page de connexion.

Voilà pourquoi dans mon contrôleur j'avais au lieu de

Listing.new -> current_user.listings.new

Dans Rails 4 les choses semblent avoir changé et je ne peux pas trouver la bonne façon de le faire.

J'ai cherché un peu et j'ai trouvé que la commande avait été changée en

before_action :authenticate_user!, :except => [:index]

Un invité peut maintenant voir l'index, mais s'il clique sur une liste, il n'est pas redirigé vers la page de connexion, mais je reçois cette erreur.

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.

Mon contrôleur d'inscriptions

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

MODIFIER: PROBLÈME 2

Si un autre utilisateur connecté essaie d'afficher une liste créée par un autre utilisateur, je reçois ceci ->

enter image description here

et le journal

enter image description here

21
Mini John

Essayez ceci, cela permettra aux invités de voir la liste fournie dans le paramètre:

def set_listing
    unless current_user
        @listing = Listing.find(params[:id])
    else
        @listing = current_user.listings.find(params[:id])
    end
end

Mise à jour:

Il semble que vous souhaitiez afficher les listes par paramètre et non par current_user. Si oui, veuillez mettre à jour votre set_listing définition comme suit:

def set_listing
    @listing = Listing.find(params[:id]) if params[:id]
end
7
vee

Appel authenticate_user avant set_listing, pour que current_user n'est pas nil

before_action :authenticate_user!, :except => [:index]
before_action :set_listing, only: [:show, :edit, :update, :destroy]
27
Santhosh