Sebastian
Sebastian

Reputation: 509

mongoid association reference to an embedded model

I have following setup

Class Country
  include Mongoid::Document

  field :name
  field :code

  has_many :locations
end

Class Location
  include Mongoid::Document

  field :country
  field :region
  field :city

  has_many :locations
  embedded_in :company
end

Class Company
  include Mongoid::Document

  field :name

  embeds_one :location
  accepts_nested_attributes_for :location
end

Countries model is seeded with all the countries.

Countries get stored with their 2-letter shortcode in Location model through a nested form. For example "US". Now I want to call @company.location.country.name in the the View to get "United States", however I'm getting an error

undefined method `name' for nil:NilClass

How do I go about doing this? What's the best way? I'm new to MongoDB so I apologize if this is a stupid question

Upvotes: 0

Views: 551

Answers (2)

Maxime Garcia
Maxime Garcia

Reputation: 610

This won't work for the given reasons (embedded & relations).

On an other side, for your issue, you shouldn't store the full name of countries in your db.

Indeed this is a "fixed" list, and to be precise, it is ISO-3166-1. Embrace the standards when there is one (rare!). A good way is to use locales (and you spare the seeding, syncing, updating parts).

Considering the file config/locales/iso-3166-1/en.yml :

en:
  countries:
    AD: "Andorra"
    AE: "United Arab Emirates"
    AF: "Afghanistan"
    AG: "Antigua and Barbuda"
    ...

Now, you can use I18n.t(@mylocation.country, :scope => :countries).

Bonus, it is i18n / l10n ready: config/locales/iso-3166-1/fr.yml :

fr:
  countries:
    AD: "Andorre"
    AE: "Émirats arabes unis"
    AF: "Afghanistan"
    AG: "Antigua-et-Barbuda"
    ...

Upvotes: 1

Cimm
Cimm

Reputation: 4775

I think your problem is related to the reverse relation you are defining on Country. Yes, a Location can have a Country but the Country can't link to the Location as it's an embedded document.

Try removing the has_many :locations in the Country class. This should solve it. Don't define a reverse relation if you don't need it.

If you need the reverse relation you probably don't want it as an embedded document.

Upvotes: 1

Related Questions