【问题标题】:Why can't I edit and destroy my pins anymore when using friendly_id?为什么我在使用friendly_id 时不能再编辑和销毁我的图钉?
【发布时间】:2015-11-30 17:48:03
【问题描述】:

我相信我正确地遵循了friendly_id github页面上的所有步骤。而且我知道它有效,因为它将我的 url 从 /1 更改为 /sample-url。但是,问题是我无法再编辑和销毁我更改了 url 的引脚。

我希望有人能帮我解决这个问题。谢谢!

/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

【问题讨论】:

    标签: ruby-on-rails friendly-id


    【解决方案1】:

    罪魁祸首是correct_user中的@pin = current_user.pins.find_by(id: params[:id])

    请注意,对于编辑、更新和销毁操作,您需要获取 pin 两次。一次在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
    

    【讨论】:

    • 感谢 AbM!这很有帮助。我从没想过 before_actions 的顺序很重要。所以对于我未来的项目,只有 authenticate_user!应该先来,所有其他人都可以不按顺序吗?
    • 顺序很重要。 before_actions 按您定义的顺序运行。如果页面需要身份验证,您可能应该首先运行authenticate_user!。在我提供的解决方案中,set_pin 必须运行第二个才能设置@pin。如果不是这种情况(即 correct_user 是第二个),则会引发错误(告诉您 nil 类没有 user_id),因为尚未定义 @pin。试试看我的意思
    • 是的,我完全明白你的意思。谢谢老哥!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多