I'm writing a Rails app which uses ActiveRecord ORM and a Postgres DB. I've got two attributes which are similar but are separate fields in the database. The assignment and saving of these is kinda complicated so I've put that side of things in their own method. The pseudo-code is as follows

myObject.attr_a = get_the_stuff_from( ref_one )
myObject.attr_b = get_the_stuff_from( ref_two )

myObject.assign_and_save( attr_a )
myObject.assign_and_save( attr_b )

Basically, how can I tell the assign_and_save method to distinguish between attr_a and attr_b so that they get saved into their respective columns in the database. I was thinking of using an additional flag for the method signature, but I think that stunts its re-usability.

What would you recommend?


1 Answer 1


Given that you're using Rails, the most common way to achieve what you're trying to do is to use a before_save or before_create ActiveRecord callback.

class Model < AR::Base
  before_save :normalize_attributes


  def normalize_attributes
    # Whatever logic you need

my_object.attr_a = get_the_stuff_from(ref_one)
my_object.attr_b = get_the_stuff_from(ref_two)

Depending on your logic, maybe get_the_stuff_from is better located in the model itself, so you might prefer something like:

class Model < AR::Base

  def set_attributes(stuff_for_a: nil, stuff_for_b: nil)
    # Something like, depending on your logic:
    self.a ||= get_the_stuff_from(stuff_for_a)
    self.b ||= get_the_stuff_from(stuff_for_b)


  def get_the_stuff_from(ref)
    # Whatever logic you need

# Either
my_object.set_attributes(stuff_for_a: ref_one)
my_object.set_attributes(stuff_for_b: ref_two)

# Or
my_object.set_attributes(stuff_for_a: ref_one,
                         stuff_for_b: ref_two)


But I don't know enough of your logic to say if the ||= is enough, but hopefully this will help.

  • 1
    ...that's an interesting approach; giving the public method a default value then calling its private counterpart with a different signature... I'd love to up-vote this but I don't have the rep. Aug 25, 2015 at 15:05
  • That's ok, another way would be to override attr_a= and attr_b=, but in my experience, sooner or later I'll regret it. Why is this not solving your problem? If it does you can accept it
    – ecoologic
    Aug 25, 2015 at 15:18
  • ok, now you have the rep (:
    – ecoologic
    Aug 25, 2015 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.