2015-11-30 1 views
2

Я считаю, что я правильно выполнил все шаги с страницы friendly_id github. И я знаю, что это работает, потому что он изменил мой url от/1 до/sample-url. Однако проблема в том, что я больше не могу редактировать и уничтожать контакты, в которых я изменил URL.Почему я не могу редактировать и уничтожать свои контакты больше при использовании friendly_id?

Я надеюсь, что кто-то может помочь мне исправить это. Спасибо!

/pins_controller.rb

class PinsController < ApplicationController 
    before_action :set_pin, only: [:show, :edit, :update, :destroy] 
    before_action :correct_user, only: [:edit, :update, :destroy] 
    before_action :authenticate_user!, except: [:index, :show] 

    respond_to :html 

    def index 
    @pins = Pin.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 8) 
    respond_with(@pins) 
    end 

    def show 
    respond_with(@pin) 
    end 

    def new 
    @pin = current_user.pins.build 
    respond_with(@pin) 
    end 

    def edit 
    end 

    def create 
    @pin = current_user.pins.build(pin_params) 
    if @pin.save 
     redirect_to @pin, notice: "Pin was successfully created." 
    else 
     render action: "new" 
    end 
    end 

    def update 
    if @pin.update(pin_params) 
     redirect_to @pin, notice: "Pin was successfully updated." 
    else 
     render action: "edit" 
    end 
    end 

    def destroy 
    @pin.destroy 
    respond_with(@pin) 
    end 

    def upvote 
    @pin = Pin.find(params[:id]) 
    @pin.upvote_by current_user 
    redirect_to :back 
    end 

    def downvote 
    @pin = Pin.find(params[:id]) 
    @pin.downvote_from current_user 
    redirect_to :back 
    end 

    private 
    def set_pin 
     @pin = Pin.friendly.find(params[:id]) 
    end 

    def correct_user 
     @pin = current_user.pins.find_by(id: params[:id]) 
     redirect_to pins_path, notice: "Not authorized to edit this pin" if @pin.nil? 
    end 

    def pin_params 
     params.require(:pin).permit(:description, :image) 
    end 
end 

/pin.rb

class Pin < ActiveRecord::Base 

    acts_as_votable 

    belongs_to :user 

    has_attached_file :image, :styles => { :medium => '300x300>', :thumb => '100x100>' } 
    validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png"] 

    validates :image, presence: true 
    validates :description, presence: true 

    extend FriendlyId 
    friendly_id :description, use: :slugged 
end 

ответ

3

Виновником в correct_user@pin = current_user.pins.find_by(id: params[:id]).

Обратите внимание, что для редактирования, обновления и уничтожения действий вы дважды извлекаете вывод. Один раз в set_pin и один раз в correct_user. В correct_user вам нужно только проверить, есть ли @pin.user_id == current_user.id.

Также, как у вас есть это сейчас, аутентификация пользователя в authenticate_user! выполняется последним, что приведет к ошибке, если не аутентифицированный пользователь отправит запрос на действие редактирования.

class PinsController < ApplicationController 
    #authenticate_user! must go first 
    before_action :authenticate_user!, except: [:index, :show] 
    before_action :set_pin, only: [:show, :edit, :update, :destroy] 
    before_action :correct_user, only: [:edit, :update, :destroy] 


    respond_to :html 

    .... your actions here 

    private 
    def set_pin 
     @pin = Pin.friendly.find(params[:id]) 
    end 

    def correct_user 
     unless @pin.user_id == current_user.id 
     redirect_to pins_path, notice: "Not authorized to edit this pin" 

     #you must return false to halt 
     false 
     end 
    end 

    def pin_params 
     params.require(:pin).permit(:description, :image) 
    end 
end 
+0

Thanks AbM! Это очень полезно. Я никогда не думал, что порядок действий до этого имеет значение. Итак, для моих будущих проектов, только authenticate_user! должен прийти первым, а все остальные в порядке, чтобы не быть в порядке? –

+0

Заказ будет иметь значение. 'Before_action' запускаются в том порядке, который вы определяете. Если на странице требуется аутентификация, вы, вероятно, сначала должны запустить «authenticate_user!». В решении, которое я предоставил, 'set_pin' должен выполнить второй, чтобы установить' @ pin'. Если бы это было не так (например, 'correct_user' был вторым), ошибка была бы повышена (сообщая вам, что класс nil не имеет' user_id'), поскольку '@ pin' еще не будет определен. Попытайтесь посмотреть, что я имею в виду. – AbM

+0

Да, я полностью понимаю, что вы имеете в виду. Спасибо друг! –

Смежные вопросы