1

I have a model object which is linked to a list of countries in a many-to-many relationship. The countries are keyed by their ISO 3166 alpha-2 codes.

The thing I'd like to accomplish is to save to use of a Country class and table, and only have my object have an accessor in the form of object.countries that will return an array of strings, e.g: ["IL", "US", "IT", ... ].

Essentially, a sort of has_and_belongs_to_many action with only the join table. Is this possible?

Is there a best practice in the case of country lists?

GeReV
  • 3,195
  • 7
  • 32
  • 44

1 Answers1

0

This is how I eventually solved it, I created a countries table in the database, as I preferred a HABTM relationship.

But to simplify things, I overrode the << operator on the collection so I could just push country codes as string or array of strings (object.country << 'IL'):

has_and_belongs_to_many(:countries) do
  def <<(country)
    if [*country].all? {|c| c.is_a?(String) }

      countries = Country.where(:code => country)
      concat(*countries)

    else

      concat(country)

    end
  end
end

You might recognize that [*...] trick from here.
Passing concat(*countries) also makes Rails insert all the rows in a single transaction, which is a nice bonus.

And added a function to return a simplified hash of codes to countries:

def countries_hash
  return self.countries.map {|c| { c.code => c.name }}.inject({}) {|hash, elem| hash.merge!(elem)}
end

Of course I'd be glad to hear any suggestions.

Community
  • 1
  • 1
GeReV
  • 3,195
  • 7
  • 32
  • 44