2013-07-28 3 views
19

I Have a Listings Controller (Elaborare Sistema) e in Rails 3 ho appena usatobefore_filter: authenticate_user !, tranne: [: indice]/Rails 4

before_filter :authenticate_user!, except: [:index] 

per verificare se un utente è stato firmato a prima di vedere un elenco specifico.

La mia home page (indice) mostra in basso una vista. Gli elenchi, l'utente è in grado di vederli, ma non appena si fa clic su uno per visualizzarlo viene reindirizzato alla pagina di accesso.

Ecco perché nel mio controller ho avuto invece di

Listing.new -> current_user.listings.new 

In Rails 4 cose sembra essere cambiato e non posso trovare il modo giusto per farlo.

ho cercato un po 'e hanno trovato che il comando è stato cambiato a

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

Come guest è possibile visualizzare ora Index, ma se si fa clic su un elenco, che non viene reindirizzato alla pagina di login, invece i ottieni questo errore

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. 

Mie proprietà 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: PROBLEMA 2

Se un altro utente connesso tenta di visualizzare un elenco che un altro utente ha creato nel mese di ottenere questo ->

enter image description here

e il registro

enter image description here

+2

U potrebbe voler fai 'authenticate_user' prima di' set_listing' – Santhosh

+0

Vuoi dire basta spostare l'utente authenticate sopra la riga set_listing? –

+0

sì. hai provato? – Santhosh

risposta

7

Prova questa, questo vi permetterà di vedere annuncio fornito nel parametro:

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

Aggiornamento:

Sembra che si desidera visualizzare le voci per parametro e non dal current_user.Se è così allora si prega di aggiornare la tua definizione set_listing come segue:

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

Ho ottenuto l'azione prima, con l'aiuto di Neo. Ma ora, se l'ho registrato, in un altro account, e provo a visualizzare un elenco che non è stato creato da me, otterrò "NoMethodError in ListingsController # mostra un metodo indefinito' listing 'per nil: NilClass ". Con il tuo codice :( –

+0

@TheMiniJohn, puoi postare la traccia dal tuo registro – vee

+0

ho modificato la domanda –

25

chiamata authenticate_user prima set_listing, in modo che current_user non è nil

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

Ha funzionato, grazie :) –

-3

sì È necessario chiamare authenticate_user prima set_listing, in modo che current_user non è nil

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

come questo

+0

In che modo questa risposta è diversa dalla mia? – Santhosh