有沒有更好的方法來做下面的代碼?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