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.send(“#{attr}=”,client.send(attr)
是为max.firm_size=client.firm_size
“编写”代码。这就是我所想的……谢谢你的参与。我猜@joofsh用“这是有争议的”来掩盖他的答案。结果证明他是对的;)与此类似的东西是我最初想到的——但是手动写出所有属性对我来说似乎有点低效。我更喜欢max.attributes
方法。我最初考虑建议使用这种方法,但出于几个原因没有这样做。1) 属性散列包含模型上的所有列,包括id、created_at、updated_at等。我猜您仍然需要显式地过滤掉这些列,这需要手动编写一些代码。2) 可读性—通过手动写出哪些列正在更新,阅读您的代码的人可以确切地知道发生了什么。如果您使用隐式方法,那么需要有人检查模式以了解真正发生了什么。这是一个很好的考虑,可读性部分。我的所有模型都有注释,因此我只为它们添加注释,以查看模型以查看属性。但是关于豁免id
,在
处创建,在
处更新以及其他类似字段的观点是非常好的。我更喜欢将一些属性列入黑名单(在本例中,只有3个)而不是将12个属性列入白名单。我强烈建议不要使用黑名单。如果您在几个月后向表中添加了一个不打算加入白名单的新字段,您可能会遇到一些奇怪的错误。很可能你已经忘记了黑名单,然后突然间