There are two models within a namespace, and they need to be associated in a many-to-many relationship with has_and_belongs_to_many. They are created like so:
$ rails generate model namespace/model_a name:string
# app/models/namespace/model_a.rb
class Namespace::ModelA < ActiveRecord::Base
end
and
$ rails generate model namespace/model_b name:string
# app/models/namespace/model_b.rb
class Namespace::ModelB < ActiveRecord::Base
end
What do I need to do successfully establish the many-to-many relationship?
I had a lot of issues getting this to work, but through a lot of parsing the Rails server error messages and a database client, I was able to massage this into working. Here is what I did:
With Rails 4, the association can be created with the has_and_belongs_to_many relationship in the models and with create_join_table in a separate migration. Of course, using the rails generators fall short of our goal. Also note that create_join_table works differently and may not even be available in previous versions of Rails.
Step 1. Generate a migration for the join table without the namespaces. We'll adjust it later.
$ rails g migration CreateModelAModelBJoinTable model_a model_b
# db/migrate/<somenumbers>_create_model_a_model_b_join_table.rb
class CreateModelAModelBJoinTable < ActiveRecord::Migration
def change
create_join_table :model_as, :model_bs do |t|
# t.index [:model_a_id, :model_b_id]
# t.index [:model_b_id, :model_a_id]
end
end
end
The migration will need some massaging. We'll need to:
Here's the final join table migration, noting the inclusion of the namespaces in the table name, but excluding the namespace in the indices. Simply, this will name the table and its indices the way that rails has_and_belongs_to_many will expect.
# db/migrate/<somenumbers>_create_model_a_model_b_join_table.rb
class CreateModelAModelBJoinTable < ActiveRecord::Migration
def change
create_join_table :model_as, :model_bs, table_name: :namespace_model_as_namespace_model_bs do |t|
t.index [:model_a_id, :model_b_id], name: :index_namespace_model_ab # or whatever, according to your database naming scheme
# t.index [:model_b_id, :model_a_id]
end
end
end
Step 2. Set up our models with the has_and_belongs_to_many associations.
In addition to the association, we need to override the class name and join table name.
# app/models/namespace/model_a.rb
class Namespace::ModelA < ActiveRecord::Base
has_and_belongs_to_many :namespace_model_b, class_name: "Namespace:ModelB", join_table: "namespace_model_as_namespace_model_bs"
end
Step 3. Run the database migrations
rake db:migrate
Final tips if you encounter issues:
You can always back out a migration, delete it, and start over as such:
$ rake db:rollback STEP=1
$ rails d migration CreateModelAModelBJoinTable
Hope this helps!