nlh
nlh

Reputation: 1055

Mongoid relation with a pre-defined object model?

Here's my use case:

I've got a collection full of sales tax rates that have been imported from CSV files. I created the Mongoid model to mirror the field names (these are not changeable):

class SalesTaxRate
  include Mongoid::Document

  field :state, type: String
  field :zip_code, type: String
  field :tax_region_name, type: String
  field :tax_region_code, type: String
  field :combined_rate, type: Float
end

Next, I'm building a model for use in my app. Let's say I want to create something called a Location:

class Location
  include Mongoid::Document

  field :name, type: String
  field :street, type: String
  field :city, type: String
  field :state, type: String
  field :zip_code, type: String
end

I'd like to be able to get a location's sales tax rate simply by calling something like this:

home = new Location(...)
home.sales_tax_rate

I'll never be setting the rate via home, just looking it up.

What's the "right" way to do this? I can think of two approaches -- the simple way seems to be just to define a method that does the lookup, as so:

class Location
  ...
  def sales_tax_rate
     SalesTaxRate.where(zip_code: self.zip_code).first.combined_rate
  end

And this works. But I'm wondering whether I should be using a belongs_to association and, if so, why and how best to do that.

Still learning the ropes here, so apologies if this is a novice/silly question. Many thanks in advance!

Upvotes: 0

Views: 136

Answers (1)

rubish
rubish

Reputation: 10907

If you have an index on zip_code in model SalesTaxRate what you are doing is essentially the same as what belongs_to will do. Just have a nil check in your code to ensure that it doesn't fail:

SalesTaxRate.where(zip_code: self.zip_code).first.try(:combined_rate)
# or
rate = SalesTaxRate.where(zip_code: self.zip_code).first
rate.nil? ? nil : rate.combined_rate

If you still want to go belongs_to route, you can define zip_code to be the identity in your SalesTaxRate. But you should take care of few things if you do that: First, all the zip codes in imported data need to be unique. Second, your location model can not have any zip code which is not available in SalesTaxRate otherwise you will face issues.

Upvotes: 1

Related Questions