Ruby on rails 合并两个ruby对象

Ruby on rails 合并两个ruby对象,ruby-on-rails,ruby,Ruby On Rails,Ruby,问:在Ruby(和/或Rails)中有没有一种简洁的方法将两个对象合并在一起 具体地说,我试图找出类似于jQuery的$.extend()方法的东西,而传入的第一个对象的属性将被第二个对象覆盖 我正在使用Rails 3.2+中的无表模型。表单提交时,提交中的参数用于动态填充用户对象。该用户对象使用Ruby的PStore类在页面请求之间持久化,将对象编组为平面文件,以便将来轻松检索 相关代码: module Itc class User include ActiveModel::Val

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

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

我正在使用Rails 3.2+中的无表模型。表单提交时,提交中的参数用于动态填充用户对象。该用户对象使用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
用户对象的创建过程如下所示:

user = Itc.User.new( params[:user] )
user.save()
merged = existingUserObject.merge(User.new(params[:user])
上面的
save()
方法不是ActiveRecord的save方法,而是我编写的通过PStore进行持久化的方法

如果加载了用户对象,并且提交了表单,我希望执行以下操作:

user = Itc.User.new( params[:user] )
user.save()
merged = existingUserObject.merge(User.new(params[:user])
并将
合并的结果
作为用户对象,仅更新表单提交中更改的属性


一般来说,如果有人对更好的方法有什么想法,我洗耳恭听。

借助hash的行为来实现。创建一个类,该类为
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))
将其倒入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
>
irb(main):001:0>Foo类
irb(主):002:1>def初始化(参数={})
irb(主):003:2>@a=params[:a]
irb(主):004:2>@b=params[:b]
irb(主):005:2>结束
irb(主要):006:1>
irb(主):007:1*def至
irb(主要):008:2>{
irb(主):009:3*a:@a,
irb(主):010:3*b:@b
irb(主):011:3>}
irb(主):012:2>结束
irb(主要):013:1>结束
无
irb(主要):014:0>
irb(main):015:0*实例a=Foo.new(a:1,b:2)
#
irb(main):016:0>实例b=Foo.new(a:1,b:3)
#
irb(主要):017:0>
irb(main):018:0*实例c=Foo.new(实例a.到h.合并(实例b.到h))
#
是不是
散列#合并
不是你要找的。看来你可以走了

merged = existingUserObject.merge(params[:user])

我认为您不需要创建一个全新的
User
对象,因为这可能就是现有的userobject,您只想覆盖一些属性。

这就是我如何在我的模型中实现类似功能的方法

  # merge other_config.attrs into self.attrs, only for nil attrs
  def merge!(other_object)
    return if other_object.nil? || other_object.class != self.class
    self.assign_attributes(self.attributes.slice ('id').merge(other_object.attributes.slice!('id')){|key, oldval, newval|
      oldval.nil? ? newval: oldval
    })
  end

锡人,背驮哈什的合并行为是一条路要走。唯一需要注意的是,我需要动态设置类属性和属性getter/setter,因此我的初始化方法如下:
def initialize(properties={})properties.each{k,v{124; class_eval(“attr_reader:{k.to_sym}”)self.instance_variable_set(@{k}),v}除非properties.nil?结束
如果您事先不知道您的实例值将是什么,那么这将起作用。就我个人而言,我更喜欢对我的对象包含的内容有更多的控制,但这就是Ruby的优点,如果我们将其编码为完全动态的,它很乐意这样做。您可能还想考虑子类哈希替代您的新对象。Hash有一些很好的特性,你可以自动继承,而不必担心创建自己的
到_h
。这应该是答案,因为它不需要任何额外的类创建,并且Hash合并功能已经烘焙到Ruby中了。是的,我同意了-我在谷歌搜索“Ruby等价于jquery extend”但从未注意到这一点,因为这不是选定的答案-(