2

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?

0

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

  private

  def normalize_attributes
    # Whatever logic you need
  end
end

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

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)
  end

  private

  def get_the_stuff_from(ref)
    # Whatever logic you need
  end
end

# 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)

my_object.save

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. – J Smith Aug 25 '15 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 '15 at 15:18
  • ok, now you have the rep (: – ecoologic Aug 25 '15 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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