Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging two ruby objects

Question: Is there a concise way in Ruby (and/or Rails) to merge two objects together?

Specifically, I'm trying to figure out something akin to jQuery's $.extend() method, whereas the first object you pass in will have its properties overridden by the second object.

I'm working with a tableless model in Rails 3.2+. When a form submission occurs, the parameters from the submission are used to dynamically populate a User object. That user object is persisted between page requests using Ruby's PStore class, marshalling objects to flat files which can be easily retrieved in the future.

Relevant code:

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

Creation of a user object occurs like this:

user = Itc.User.new( params[:user] )
user.save()

The save() method above is not ActiveRecord's save method, but a method I wrote to do persistence via PStore.

If I have a user object loaded, and I have a form submission, I'd like to do something like this:

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

and have the outcome of merged be a user object, with only properties that were changed in the form submission be updated.

If anyone has any ideas about a better way to do this in general, I'm all ears.

like image 442
jiveTurkey Avatar asked Aug 07 '12 20:08

jiveTurkey


People also ask

How do you merge hashes in Ruby?

We can merge two hashes using the merge() method. When using the merge() method: Each new entry is added to the end. Each duplicate-key entry's value overwrites the previous value.


1 Answers

Is Hash#merge not what you're looking for? http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-merge. Seems like you could just go

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

I don't think you need to create an entirely new User object since presumably that's what existingUserObject is and you just want to overwrite some properties.

like image 159
JGrubb Avatar answered Sep 28 '22 03:09

JGrubb