Rails: Many-to-many flattening with only the join table

空扰寡人 提交于 2019-12-11 05:56:53

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/7970965/rails-many-to-many-flattening-with-only-the-join-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!