【问题标题】:Activerecord find_by_id strange behaviorActiverecord find_by_id 奇怪的行为
【发布时间】:2016-06-23 06:11:15
【问题描述】:

考虑我在控制器中有这样的 show 方法:

class ThingsController < ApplicationController
    def show
        thing = Thing.find_by_id(params[:id])
        render json: 'Not Found', status: :not_found and return if !thing
        render json: thing.to_json, status: :ok
    end
end

数据库中只有 1 条 id=1 的记录。

现在,这是我的测试:

  1. 当我调用 /things/1 时,我可以获得记录。
  2. 当我调用 /things/2 时,我得到 404。
  3. 当我调用 /things/a1 时,我得到 404。
  4. 当我调用 /things/1a 时,我预计会出错,但它给了我 id=1 的记录。

#4 正常吗?如何预防?

Rails 版本:4.2.6

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    .find_by_id() 方法将传入的参数转换为整数,因为1a.to_i1,所以它返回一个记录值。

    如果您想防止这种情况发生,您必须检查传入的 param[:id] 是否仅包含数字。

    '1a' !~ /\D/                # false
    '12' !~ /\D/                # true
    
    # So, use it in the if
    params[:id] !~ /\D/
    

    【讨论】:

    • 如果我将 id 的数据类型设为字符串,那么 find_by_id 不会 to_i 参数对吗?例如。 /things/1a2b 和 /things/3c4d 将找到 1a2b 和 3c4d 的完全匹配?
    【解决方案2】:

    因为 id 的类型是整数,所以活动记录会在使用to_i 函数创建查询字符串之前将其转换为整数。如果您不希望用户通过这样的链接访问详细信息,有很多方法可以防止,例如适合您:

    1.Validate params[:id] 是ThingsController中的数字

    2.在Thing中创建类方法find_by_id

    class class Thing < ActiveRecord::Base   
      def self.find_by_id(id)
        validate_type_id!(id) # Have to define the function to raise not found exception if invalid format type
        super   
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-17
      • 2011-12-23
      相关资源
      最近更新 更多