Why can't I edit and destroy my pins anymore w

2019-08-14 08:40发布

I believe I followed all the steps correctly from the friendly_id github page. And I know it works because it changed my url from /1 to /sample-url. However, the problem is I can't edit and destroy anymore the pins in which the url I have changed.

I hope someone can help me fix this one. Thank you!

/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

1条回答
【Aperson】
2楼-- · 2019-08-14 09:38

The culprit is @pin = current_user.pins.find_by(id: params[:id]) in correct_user.

Note that for edit, update and destroy actions, you are fetching the pin twice. Once in set_pin and once in correct_user. In the correct_user, you only need to check if the @pin.user_id == current_user.id.

Also, the way you have it now, your user authentication in authenticate_user! runs last, which will cause an error if an unauthenticated user submits a request to the edit action.

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
查看更多
登录 后发表回答