修改 URL 中的 ID 以避免猜测 Rails 中的不同整数 ID

Modified ID in URLs to avoid guessing different integer IDs in Rails

我问的问题几乎和这里问的一样:Encrypted ID in URLs

只是我不一定要加密ID,我用的是随机串码。我已经尝试了与 João Carlos Ottobboni 回答类似的解决方案,使用 FriendlyId,如下所示:

在我的 models/coupon.rb

class Coupon < ApplicationRecord
  extend FriendlyId
  friendly_id :code #code is already a coupon column

  validates :code, uniqueness: true
  before_create :generate_code

  def generate_code
    all_letters = [('A'..'Z'), ('0'..'9')].map(&:to_a).flatten
    random_string = (0...6).map { all_letters [rand(36)] }.join
    self.code = random_string
  end

在我的 controllers/coupon_controller.rb

class CouponsController < ApplicationController
before_action :set_coupon, only: [:show, :edit, :update, :redeem, :destroy]
...
  private
    def set_coupon
      @coupon = Coupon.friendly.find(params[:id])
    end

当我被重定向到一个特定的优惠券路径时,它确实有效,将我重定向到 coupons/SJKE3K 而不是 coupons/13。但这并不能阻止我在 url 中输入 13,它也会重定向我。我怎样才能避免这种情况?我需要优惠券只能通过代码而不是通过 id 访问。

Coupon.friendly.find(params[:id]) 允许使用 code 和 id 来查找记录。如果您切换到 Coupon.find_by!(code: params[:id]) 只有代码才能找到优惠券。

在这种情况下,您根本不需要 Friendly ID,您可以继续手动生成代码并使用它查找记录。

在生成使用优惠券的表单或包含优惠券的路线时,这将需要做更多的工作,因为默认情况下这些将始终使用整数 ID - 您必须显式传递 id: coupon.code 作为参数给 url/path 助手并在创建表单时传递 url: my_path(id: coupon.code) 或类似的东西。