Ruby对象质量分配

时间:2016-01-20 17:30:46

标签: ruby accessor

有没有更好的方法来执行以下代码?

user.name = "abc"
user.email = "abc@test.com"
user.mobile = "12312312"

这样的事情会:

user.prepare do |u|
  u.name = "abc"
  u.email = "abc@test.com"
  u.mobile = "12312312"
end

5 个答案:

答案 0 :(得分:8)

tap让你这样做:

user.tap do |u|
  u.name = "abc"
  u.email = "abc@test.com"
  u.mobile = "12312312"
end

答案 1 :(得分:0)

当您的属性以散列形式出现时的替代选项:

attrs = {
  name: "abc",
  email: "abc@test.com",
  mobile: "12312312"
}

attrs.each { |key, value| user.send("#{key}=", value) }

答案 2 :(得分:0)

使用ActiveRecord对象,您可以使用.assign_attributes或更新 方法:

user.assign_attributes( name: "abc", email: "abc@test.com", mobile: "12312312")
# attributes= is a shorter alias for assign_attributes
user.attributes = { name: "abc", email: "abc@test.com", mobile: "12312312" }

# this will update the record in the database
user.update( name: "abc", email: "abc@test.com", 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: "abc@test.com", mobile: "12312312")
u.attributes = { email: "abc@example.com", name: "joe" }
u.assign_attributes(name: 'bob') do |u|
  u.email = "#{u.name}@example.com"
end

# etc.

答案 3 :(得分:0)

您也可以执行以下操作:

muc#roomconfig_presencebroadcast

您可以访问user.instance_eval do @name = "abc" @email = "abc@test.com" @mobile = "12312312" end

块内的user实例变量

如果您希望调用访问器方法而不是直接操作实例变量,则可以使用以下代码。

instance_eval

user.instance_eval do
    self.name = "xyz"
    self.email = "abc@test.com"
    self.mobile = "12312312"
end

答案 4 :(得分:0)

假设'用户'是您控制的类,然后您可以定义一个方法来执行您想要的操作。例如:

def set_all(hash)
  @name, @email, @mobile = hash[:name], hash[:email], hash[:mobile]
end

然后在你的其余代码中:

user.set_all(name: "abc", email: "abc@test.com", mobile: "12312312")

如果'用户'是一个ActiveRecord模型的实例,然后我对如何使其工作的细节略显不稳定。但是校长仍然适用:通过将复杂性的责任移交给接收者来干掉代码。