Ask A Question

Notifications

You’re not receiving notifications from this thread.

Building has_one from has_many Associations Discussion

Great tip! I use something similar for designating the thumbnail-image of a gallery of images. Something along these lines:

class Gallery
  has_many :images
  has_one :thumbnail, -> { where(thumbnail: true) }, class_name: "Image"
end

One of the benefits over this approach versus having a regular thumbnail method, is that you can eager-load the thumbnails and prevent N+1 problems using @galleries = Gallery.includes(:thumbnail)

If you need more flexibility, I think you can also use DelegatedTypes. For example if ShippingAddress needs a specific attribute or logic that BillingAddress doesn't need.

Reply

And since the enum has created scopes for billing and shipping, you can DRY those associations up a little with:

has_one :billing_address,  -> { merge(Address.billing) }, class_name: "Address"
has_one :shipping_address, -> { merge(Address.shipping) }, class_name: "Address"
Reply

Since the target of merge is already an Address collection, you can even use the scope methods directly:

has_one :billing_address,  -> { billing },  class_name: :Address
has_one :shipping_address, -> { shipping }, class_name: :Address
Reply

Super nice!

Reply

yeah, I wondered why he didn't just put billing and shipping in the scopes... glad to know that the scopes work normally from this context

Reply

Thanks for the video!

Don't forget to also add unique constraints at the database level to make sure an Account can only have one shipping and one billing address.

Reply

thanks, i keep wondering how to avoid incorrect get first billing / address

Reply

Thanks all for contributing to the conversation! I've added a link to a blog post in the episode notes about this topic and included some things around validating uniqueness.

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 86,796+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.