Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如果我有10个属性,如果条件正确,我希望更新这些属性,我该怎么做?_Ruby On Rails_Ruby On Rails 3 - Fatal编程技术网

Ruby on rails 如果我有10个属性,如果条件正确,我希望更新这些属性,我该怎么做?

Ruby on rails 如果我有10个属性,如果条件正确,我希望更新这些属性,我该怎么做?,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,假设我在我的客户机上有一组属性,如下所示: # firm_size :float # priority_level :float # inflection_point :float # personal_priority :float # sales_priority :float # sales_team_priority :float # days_sinc

假设我在我的
客户机上有一组属性,如下所示:

#  firm_size                 :float
#  priority_level            :float
#  inflection_point          :float
#  personal_priority         :float
#  sales_priority            :float
#  sales_team_priority       :float
#  days_since_contact        :float
#  does_client_vote          :float
#  did_client_vote_for_us    :float
#  days_until_next_vote      :float
#  does_client_vote_ii       :float
#  did_client_vote_ii_for_us :float
#  days_until_vote_ii        :float
max = Max.find_or_create_by_user_id(:user_id => current_user.id)

if client.firm.size > max.firm_size
    max.firm_size = client.firm.size
end

if client.inflection_point > max.inflection_point
    max.inflection_point = client.inflection_point
end
我需要对每个属性进行如下检查:

#  firm_size                 :float
#  priority_level            :float
#  inflection_point          :float
#  personal_priority         :float
#  sales_priority            :float
#  sales_team_priority       :float
#  days_since_contact        :float
#  does_client_vote          :float
#  did_client_vote_for_us    :float
#  days_until_next_vote      :float
#  does_client_vote_ii       :float
#  did_client_vote_ii_for_us :float
#  days_until_vote_ii        :float
max = Max.find_or_create_by_user_id(:user_id => current_user.id)

if client.firm.size > max.firm_size
    max.firm_size = client.firm.size
end

if client.inflection_point > max.inflection_point
    max.inflection_point = client.inflection_point
end
其他属性也是如此,但这对我来说似乎很不干燥


如何以优雅的方式实现这一点,而不必为所有属性键入10亿个
if语句?

如果将所有属性放在一个数组中,可以对其进行迭代,并使用一些元编程,只需编写一次逻辑:

good_attrs = %w(firm_size priority_level ...)

good_attrs.each do |attr|
  if client.send(attr) > max.send(attr)
    max.send("#{attr}=", client.send(attr)
  end
end

如果将所有属性放在一个数组中,可以对其进行迭代,并使用一些元编程,只需编写一次逻辑:

good_attrs = %w(firm_size priority_level ...)

good_attrs.each do |attr|
  if client.send(attr) > max.send(attr)
    max.send("#{attr}=", client.send(attr)
  end
end

您可以使用类似的方法(不确定我是否正确理解您的对象)


几乎一样…

您可以使用类似的东西(不确定我是否正确理解您的对象)

几乎一样…

这个怎么样:

Client.column_names.each do |attr_name|
  if (client_val = client.send(attr_name)) > max.send(attr_name)
    max.write_attribute(attr_name, client_val) 
  end
end
我在这里假设您希望迭代
客户机
模型的所有属性,但从上面的注释线程来看,情况似乎并非如此。

这是怎么回事:

Client.column_names.each do |attr_name|
  if (client_val = client.send(attr_name)) > max.send(attr_name)
    max.write_attribute(attr_name, client_val) 
  end
end

我在这里假设您希望迭代
客户机
模型的所有属性,但从上面的注释线程来看,情况似乎并非如此。

首先,我将在您的
客户机.rb
模型中创建一个白名单方法,列出您希望用于此类比较的属性

def self.comparable_attrs
  %w(firm_size priority_level inflection_point personal_priority ...)
end
然后,您可以使用
send()
方法遍历所有良好属性

Client.comparable_attrs.each do |attr|
  if client.send(attr) > max.send(attr)
    max.send("#{attr}=", client.send(attr))
  end
end

首先,我将在您的
client.rb
属性模型中创建一个白名单方法,用于进行此类比较

def self.comparable_attrs
  %w(firm_size priority_level inflection_point personal_priority ...)
end
然后,您可以使用
send()
方法遍历所有良好属性

Client.comparable_attrs.each do |attr|
  if client.send(attr) > max.send(attr)
    max.send("#{attr}=", client.send(attr))
  end
end


我假设您键入错误:
client.firm.size
应该是
client.firm\u size
,对吗?否。
size
是模型上的一个属性
firm
client
firm
是相关的。嗯。这使得编写一个适用于所有属性的通用解决方案变得非常困难。我假设您输入错误:
client.firm.size
应该是
client.firm\u size
,对吗?不。
size
是模型上的一个属性
firm
client
firm
是相关的。嗯。这使得编写一个适用于所有属性的通用解决方案变得非常困难。你能给我解释一下
send
在这里做什么吗?它是一种用字符串或符号进行方法调用的方法。因此在这个循环中,
|attr |
值都是字符串。所以你不能做最大的“公司大小”
这是行不通的。相反,你可以做<代码> Max。发送(“固件大小”),它与 Max .SimultSimule完全相同,我想这是有争议的,但不,我不认为这是代码>元编程< /代码>。元编程是编写生成其他代码的代码。当然,这是一个更高的抽象级别。对于它的价值,我不同意@ JooSH,并且会考虑任何类型的动态调度是元编程。如果您的定义是“编写代码的代码”,那么这绝对是元编程。如果“attr”是“firm_size”,那么
max.send(“#{attr}=”,client.send(attr)
是为
max.firm_size=client.firm_size
“编写”代码。这就是我所想的……谢谢你的参与。我猜@joofsh用“这是有争议的”来掩盖他的答案。结果证明他是对的;)你能解释一下
send
在这里做什么吗?它是一种用字符串或符号进行方法调用的方法。因此在这个循环中,
|attr |
值都是字符串。所以你不能做最大的“公司大小”
这是行不通的。相反,你可以做<代码> Max。发送(“固件大小”),它与 Max .SimultSimule完全相同,我想这是有争议的,但不,我不认为这是代码>元编程< /代码>。元编程是编写生成其他代码的代码。当然,这是一个更高的抽象级别。对于它的价值,我不同意@ JooSH,并且会考虑任何类型的动态调度是元编程。如果您的定义是“编写代码的代码”,那么这绝对是元编程。如果“attr”是“firm_size”,那么
max.send(“#{attr}=”,client.send(attr)
是为
max.firm_size=client.firm_size
“编写”代码。这就是我所想的……谢谢你的参与。我猜@joofsh用“这是有争议的”来掩盖他的答案。结果证明他是对的;)与此类似的东西是我最初想到的——但是手动写出所有属性对我来说似乎有点低效。我更喜欢
max.attributes
方法。我最初考虑建议使用这种方法,但出于几个原因没有这样做。1) 属性散列包含模型上的所有列,包括id、created_at、updated_at等。我猜您仍然需要显式地过滤掉这些列,这需要手动编写一些代码。2) 可读性—通过手动写出哪些列正在更新,阅读您的代码的人可以确切地知道发生了什么。如果您使用隐式方法,那么需要有人检查模式以了解真正发生了什么。这是一个很好的考虑,可读性部分。我的所有模型都有注释,因此我只为它们添加注释,以查看模型以查看属性。但是关于豁免
id
处创建,
处更新以及其他类似字段的观点是非常好的。我更喜欢将一些属性列入黑名单(在本例中,只有3个)而不是将12个属性列入白名单。我强烈建议不要使用黑名单。如果您在几个月后向表中添加了一个不打算加入白名单的新字段,您可能会遇到一些奇怪的错误。很可能你已经忘记了黑名单,然后突然间