有没有更好的方法来做下面的代码?Ruby对象质量分配
user.name = "abc"
user.email = "[email protected]"
user.mobile = "12312312"
像这样的东西会做:
user.prepare do |u|
u.name = "abc"
u.email = "[email protected]"
u.mobile = "12312312"
end
有没有更好的方法来做下面的代码?Ruby对象质量分配
user.name = "abc"
user.email = "[email protected]"
user.mobile = "12312312"
像这样的东西会做:
user.prepare do |u|
u.name = "abc"
u.email = "[email protected]"
u.mobile = "12312312"
end
tap让我们这样做正是:
user.tap do |u|
u.name = "abc"
u.email = "[email protected]"
u.mobile = "12312312"
end
替代选项:
attrs = {
name: "abc",
email: "[email protected]",
mobile: "12312312"
}
attrs.each { |key, value| user.send("#{key}=", value) }
用ActiveRecord对象可以使用.assign_attributes
或更新 方法:
user.assign_attributes(name: "abc", email: "[email protected]", mobile: "12312312")
# attributes= is a shorter alias for assign_attributes
user.attributes = { name: "abc", email: "[email protected]", mobile: "12312312" }
# this will update the record in the database
user.update(name: "abc", email: "[email protected]", mobile: "12312312")
# or with a block
user.update(name: "abc", mobile: "12312312") do |u|
u.email = "#{u.name}@test.com"
end
.update
接受一个块,而assign_attributes没有。如果你只是简单地分配一个文字值的哈希值 - 比如用户在参数中传递的值,那么就不需要使用一个块。
如果你有,你想与质量分配香料一个普通的老红宝石对象,你可以这样做:
class User
attr_accessor :name, :email, :mobile
def initialize(params = {}, &block)
self.mass_assign(params) if params
yield self if block_given?
end
def assign_attributes(params = {}, &block)
self.mass_assign(params) if params
yield self if block_given?
end
def attributes=(params)
assign_attributes(params)
end
private
def mass_assign(attrs)
attrs.each do |key, value|
self.public_send("#{key}=", value)
end
end
end
这将让你做的事:
u = User.new(name: "abc", email: "[email protected]", mobile: "12312312")
u.attributes = { email: "[email protected]", name: "joe" }
u.assign_attributes(name: 'bob') do |u|
u.email = "#{u.name}@example.com"
end
# etc.
你可以做到以下几点以及:
user.instance_eval do
@name = "abc"
@email = "[email protected]"
@mobile = "12312312"
end
您可以访问内部的实例变量user
块给instance_eval
,如果你想调用存取方法,而不是直接操作实例变量你可以使用下面的代码。
user.instance_eval do
self.name = "xyz"
self.email = "[email protected]"
self.mobile = "12312312"
end
或
user.instance_eval do |o|
o.name = "xyz"
o.email = "[email protected]"
o.mobile = "12312312"
end
假设“用户”是你控制的一类,那么你可以定义做你想要的东西的方法。例如:
def set_all(hash)
@name, @email, @mobile = hash[:name], hash[:email], hash[:mobile]
end
然后在你的代码的其余部分:
user.set_all(name: "abc", email: "[email protected]", mobile: "12312312")
如果“用户”是的,比方说,一个ActiveRecord模型的实例,然后我就有点动摇你如何得到这个工作的细节。但校长仍然适用:通过将复杂性的责任移交给接收者来干代码。
[DRY方式为对象分配散列值]的可能副本(http://stackoverflow.com/questions/3669801/dry-way-to-assign-hash-values-to-an-object) –
如果'user'是一个'ActiveRecord',那么['attributes ='](http://apidock.com/rails/ActiveRecord/AttributeAssignment/assign_attributes)可能是一个选项。 – spickermann
为什么你喜欢你的第二个例子比第一个更好? – spickermann