0

I have the following virtual attributes within my model:

attr_accessor :city, :zip, :street, :suite

In the new/edit form, I have form fields for each of these attributes. I can convert these four attributes into a single address_id with a method we'll call address_lookup. I only need to store the address_id in the model. What's the basic approach to cleanly handle this in the create/update controller actions, and (if necessary) the model? It's a little over my head.

Tim Koelkebeck
  • 795
  • 2
  • 9
  • 18

1 Answers1

1

Simplest is to add in a before_save callback, we'll use the changed array to check whether any of the attributes we're interested in have changed before we do our lookup:

before_save :set_address

def set_address
  if address = Address.find_or_create_by( city: city, zip: zip, street: street, suite: suite)
    self.address = address
  end
end
smathy
  • 26,283
  • 5
  • 48
  • 68
  • awesome, testing this out now – Tim Koelkebeck Feb 09 '15 at 20:50
  • how are the user entered city/zip/street/suite values accessed? I tried Address.find_or_create_by( city: self.city, zip: self.zip .. ) but self.city, self.zip etc each return blank/null. Same thing happens when I have it typed up exactly as shown in your example, without self. I should note that I'm not using your changed comparison, because for this phase of development I need to update the record every time, regardless of whether it's been changed. – Tim Koelkebeck Feb 09 '15 at 21:43
  • Well, I assume that in your controller you were setting the model attributes to the incoming form values, eg. `@markup = Markup.find params[:id]; if @markup.update(markup_params); # etc..` with something like: `def markup_params; params.require(:markup).permit(:other,:things,:and, :city, :zip, :street, :suite); end` – smathy Feb 09 '15 at 22:29
  • in the flow I'm testing now it's always a new record, I do pass all the values from the form inputs, and then in create do the standard @markup = Markup.new(markup_params) and if markup.save, etc. Are you saying I need to define markup_params in the model now? – Tim Koelkebeck Feb 09 '15 at 22:42
  • No, just in the controller. Oh, I forgot about the fact that `changed` only works on real DB attributes (not virtual attributes like you have), I've just updated my answer to remove that check and I replaced it with a check to ensure that we were able to find/create the `Address` instance. – smathy Feb 09 '15 at 22:51
  • ...and just to confirm with you, the original `city: city, etc..` that I had is correct, the values of that hash are the getter methods that you defined with `attr_accessor`. Here's some example code showing this in an irb session: https://gist.github.com/smathy/ded075c28c982887bef1 – smathy Feb 09 '15 at 22:56
  • I got this working. I'm used to the scaffolding defining markup_params and didn't think to update it, and also a blank form entry was getting passed as a blank string when I needed it to be nil, which was screwing up my find. Thanks for your help! – Tim Koelkebeck Feb 10 '15 at 00:36