合并两个红宝石对象

jiv*_*key 8 ruby ruby-on-rails

问题:Ruby(和/或Rails)中是否有一种简洁的方法将两个对象合并在一起?

具体来说,我正在尝试找出类似于jQuery $.extend()方法的东西,而传入的第一个对象将使其属性被第二个对象覆盖.

我正在使用Rails 3.2+中的无表格模型.发生表单提交时,提交中的参数用于动态填充User对象.该用户对象在使用Ruby的PStore类的页面请求之间保持不变,将对象编组为平面文件,以后可以轻松检索.

相关代码:

module Itc
  class User
    include ActiveModel::Validations
    include ActiveModel::Conversion
    include ActionView::Helpers
    extend ActiveModel::Naming

    def set_properties( properties = {} )
      properties.each { |k, v|
        class_eval("attr_reader :#{k.to_sym}")
        self.instance_variable_set("@#{k}", v)
      } unless properties.nil?
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

创建用户对象的方式如下:

user = Itc.User.new( params[:user] )
user.save()
Run Code Online (Sandbox Code Playgroud)

save()上面的方法不是ActiveRecord的save方法,而是我写的一个通过PStore执行持久化的方法.

如果我加载了一个用户对象,并且我有一个表单提交,我想做这样的事情:

merged = existingUserObject.merge(User.new(params[:user])
Run Code Online (Sandbox Code Playgroud)

并且结果merged是用户对象,只更新表单提交中更改的属性.

如果有人对一般的更好的方法有任何想法,我会全力以赴.

JGr*_*ubb 7

Hash#merge不是你想要的?http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-merge.好像你可以去

merged = existingUserObject.merge(params[:user])
Run Code Online (Sandbox Code Playgroud)

我不认为你需要创建一个全新的User对象,因为大概是现有的UserObject是什么,你只想覆盖一些属性.


the*_*Man 5

通过捎带散列的行为来做到这一点。创建一个类,该类接受new()方法参数的哈希值,然后创建一个to_h方法,该方法接受对象并从实例的当前状态生成哈希值:

class Foo
  def initialize(params={})
    @a = params[:a]
    @b = params[:b]
  end

  def to_h
    {
      a: @a,
      b: @b
    }
  end
end

instance_a = Foo.new(a: 1, b:2)
instance_b = Foo.new(a: 1, b:3)

instance_c = Foo.new(instance_a.to_h.merge(instance_b.to_h))
Run Code Online (Sandbox Code Playgroud)

将其转储到 IRB:

irb(main):001:0> class Foo
irb(main):002:1>   def initialize(params={})
irb(main):003:2>     @a = params[:a]
irb(main):004:2>     @b = params[:b]
irb(main):005:2>   end
irb(main):006:1> 
irb(main):007:1*   def to_h
irb(main):008:2>     {
irb(main):009:3*       a: @a,
irb(main):010:3*       b: @b
irb(main):011:3>     }
irb(main):012:2>   end
irb(main):013:1> end
nil
irb(main):014:0> 
irb(main):015:0* instance_a = Foo.new(a: 1, b:2)
#<Foo:0x1009cfd00
    @a = 1,
    @b = 2
>
irb(main):016:0> instance_b = Foo.new(a: 1, b:3)
#<Foo:0x1009ead08
    @a = 1,
    @b = 3
>
irb(main):017:0> 
irb(main):018:0* instance_c = Foo.new(instance_a.to_h.merge(instance_b.to_h))
#<Foo:0x100a06c60
    @a = 1,
    @b = 3
>
Run Code Online (Sandbox Code Playgroud)

  • Tin Man,利用 hash 的合并行为是要走的路。唯一需要注意的是我需要动态设置类属性和属性 getter/setter,所以我的初始化方法如下所示:`def initialize(properties = {}) properties.each { |k, v| class_eval("attr_reader :#{k.to_sym}") self.instance_variable_set("@#{k}", v) } 除非 properties.nil?结束` (2认同)