Ruby on rails 在rails 4中的where条件中使用字符串变量作为字段名

Ruby on rails 在rails 4中的where条件中使用字符串变量作为字段名,ruby-on-rails,ruby-on-rails-4,Ruby On Rails,Ruby On Rails 4,我在控制器中有一个方法,检查数据库中是否已经存在字段值。在我的例子中,我必须通过AJAX检查多个字段,如用户名、电子邮件和URL 所以我写了下面的函数 def check_field_already_exist?(field, params ) merchant_url = MerchantUrl.where(field: filter_params[field.to_sym]).first # here params[:id] is available only wh

我在控制器中有一个方法,检查数据库中是否已经存在字段值。在我的例子中,我必须通过AJAX检查多个字段,如用户名、电子邮件和URL

所以我写了下面的函数

  def check_field_already_exist?(field, params )

    merchant_url = MerchantUrl.where(field: filter_params[field.to_sym]).first

     # here params[:id] is available only while editing the MerchantUrl
     is_available = if (params[:id] && merchant_url)
                 merchant_url.id == params[:id]
               else
                 merchant_url.blank?
               end
  end
并调用此方法作为

  def is_name_available
    render json: check_field_already_exist?('username', params)
  end

  def is_url_available
    render json: check_field_already_exist?('url', params)
  end

  def is_email_available
    render json: check_field_already_exist?('email', params)
  end
但在执行时,它会抛出错误

Mysql2::错误:在“where子句”中的未知列“商户URL.field”:从
商户URL
中选择
商户URL
*,其中
商户URL
字段=”

那么,有没有任何方法可以使用字符串变量作为字段名?
谢谢。

我觉得你做得不对。当您将id传递到方法中(在params中)时,为什么不使用该id获取
商户url
,然后检查字段是否包含以下内容:

def check_field_already_exist?(field, id=nil)
  if id && merchant_url = MerchantUrl.find(id)
    merchant_url.send(field).try('present?')
  else
    MerchantUrl.exists?(field => filter_params[field.to_sym])
  end 
end
那么你可以

def is_name_available
  render json: check_field_already_exist?('username', params[:id])
end

虽然就我个人而言,我有一个方法将模型实例属性散列返回为json,然后使用JavaScript客户端检查散列的内容。这样,您只需向服务器回拨一次(而不是每个字段回拨一次)即可获得所需的数据。

在我看来,您这样做是错误的。当您将id传递到方法中(在params中)时,为什么不使用该id获取
商户url
,然后检查字段是否包含以下内容:

def check_field_already_exist?(field, id=nil)
  if id && merchant_url = MerchantUrl.find(id)
    merchant_url.send(field).try('present?')
  else
    MerchantUrl.exists?(field => filter_params[field.to_sym])
  end 
end
那么你可以

def is_name_available
  render json: check_field_already_exist?('username', params[:id])
end

虽然就我个人而言,我有一个方法将模型实例属性散列返回为json,然后使用JavaScript客户端检查散列的内容。这样,您只需向服务器回拨一次(而不是每个字段回拨一次)即可获得所需的数据。

在yor code
中,字段是标识列名的符号。
你应该这样做:

merchant_url = MerchantUrl.where("#{field} = ?", filter_params[field.to_sym])

在YR code
field
中,是标识列名称的符号。 你应该这样做:

merchant_url = MerchantUrl.where("#{field} = ?", filter_params[field.to_sym])
我希望这能奏效

def check_field_already_exist?(field, params )

    merchant_url = MerchantUrl.where("#{field}=?", filter_params[field.to_sym]).first

    is_available = if (params[:id] && merchant_url)
                     merchant_url.id == params[:id]
                   else
                     merchant_url.nil?
                   end
  end
但请确保
字段不应是最终用户可以通过参数设置的内容。。另一方面,它会非常脆弱。

我希望这能奏效

def check_field_already_exist?(field, params )

    merchant_url = MerchantUrl.where("#{field}=?", filter_params[field.to_sym]).first

    is_available = if (params[:id] && merchant_url)
                     merchant_url.id == params[:id]
                   else
                     merchant_url.nil?
                   end
  end
但请确保
字段不应是最终用户可以通过参数设置的内容。。另一方面,它将非常容易受到攻击。

正确的方法是使用良好的旧hashrocket语法

merchant_url = MerchantUrl.where(field => filter_params[field])
正确的方法是使用旧的hashrocket语法

merchant_url = MerchantUrl.where(field => filter_params[field])


谢谢你ReggieB我没有在所有情况下都有params[:id]。我在new和edit案例中使用相同的方法。因此,如果我验证新表单,它不会传递id,但如果是编辑表单,它会传递id。@bipashant我已经修改了我的答案,以便在没有id的情况下它会工作(在这种情况下,它将返回nil)。@bipashant我再次修改了我的答案,因此,如果没有现有的字段,它将检查其他商家URL中的字段。您好,非常感谢,但我收到了这个错误ArgumentError(参数数量错误(2代表0..1)):app/controllers/merchant\u urls\u controller.rb:44:in
检查\u字段是否已存在?'app/controllers/merchant\u urls\u controller.rb:16:in
是否可用当参数[:id]为nillid]时,您注意到我已交换了
中参数的顺序是否可用
?谢谢您,我在所有情况下都没有参数[:id]。我在new和edit案例中使用相同的方法。因此,如果我验证新表单,它不会传递id,但如果是编辑表单,它会传递id。@bipashant我已经修改了我的答案,以便在没有id的情况下它会工作(在这种情况下,它将返回nil)。@bipashant我再次修改了我的答案,因此,如果没有现有的字段,它将检查其他商家URL中的字段。您好,非常感谢,但我收到了这个错误ArgumentError(参数数量错误(2代表0..1)):app/controllers/merchant\u url\u controller.rb:44:in
检查\u字段是否已存在?'app/controllers/merchant\u url\u controller.rb:16:in
当参数为[:id]时,名称是否可用您是否注意到我在
是否有可用的
中交换了参数的顺序?我很惊讶这在
中起作用,其中
将返回一组商户url实例。因此,以下
merchant\u url.id
将出错或返回集合的id。您可以使用
find_by
而不是
where
,但这样会找到第一个,并且可能会错过您要找的那个。您可以尝试
mechant\u url.collect(&:id).include?(params[:id])
或使用我的替代方案。我认为如果您相应地编辑您的答案会更好@ReggieBMy answer如果没有现有的商户url,则只需执行
where
查询即可解决此问题。-因此,我认为没有必要对其进行编辑。不管怎样,您上面的第一条评论确实很有帮助,请注意,我感到惊讶的是,这条评论作为
工作,其中
将返回一组merchant_url实例。因此,以下
merchant\u url.id
将出错或返回集合的id。您可以使用
find_by
而不是
where
,但这样会找到第一个,并且可能会错过您要找的那个。您可以尝试
mechant\u url.collect(&:id).include?(params[:id])
或使用我的替代方案。我认为如果您相应地编辑您的答案会更好@ReggieBMy answer如果没有现有的商户url,则只需执行
where
查询即可解决此问题。-所以我不认为有必要编辑它。不管怎样,你上面的第一条评论真的很有帮助,谢谢