administrate icon indicating copy to clipboard operation
administrate copied to clipboard

Models with relationships through join tables not supported

Open cristianriano opened this issue 4 years ago • 6 comments

  • What were you trying to do?

I have a relationship many-to-many (HABTM) in my code (cocktails..ingredients). I used the ActiveRecord method create_join_table to create the join table (portions), which means it has no ID field on it's own. For the model I declared the relationship both with has_and_belongs_to_many and has_many ... through:. Then I generated the dashboards and controllers for my app and try to visit the show of one of the instances

  • What did you end up with (logs, or, even better, example apps are great!)?

I get a ActionController::UrlGenerationError in Admin::Cocktails#show error

No route matches {:action=>"show", :controller=>"admin/portions", :id=>nil}, missing required keys: [:id]

  • What versions are you running?
    • Ruby 3.0.0
    • Rails 6.1.1
    • Administrate 0.14

I know it's happening because the join table doesn't have an ID, but how is this case mean to be handled with the gem? Is there something I'm missing or I just need to add the ID?

cristianriano avatar Feb 04 '21 14:02 cristianriano

Associations of type has_and_belongs_to_many, using a join table like the one you describe, do work with Administrate. I just had a quick check and could get it working.

Your error mentions a different dashboard "portions". Could it be this is the one causing trouble? What does your dashboard look like? What models are involved? What are their associations?

pablobm avatar Feb 04 '21 17:02 pablobm

I added an id field to the join table and then it works. But if I use the helper create_join_table it does not add an id to the join table (because it doesn't need one on it's own)

I have 3 models cocktail - portions - ingredients

Portions have both a cocktail_id and ingredient_id

cristianriano avatar Feb 05 '21 14:02 cristianriano

OK, cool. I'm going to close the issue for now then.

If anyone else has the same issue, please let us know on this thread. If you can provide detail as to what your tables look like, which relationships you use, which Administrate fields you use, etc, that would be great.

pablobm avatar Feb 11 '21 15:02 pablobm

FYI, I ran into this as another ticket. You use the AR resources and don't mention the join tables in Administrate and it seems to work.

wflanagan avatar Feb 22 '21 19:02 wflanagan

Sorry @pablobm I didn't see your comment.

So for someone else checking this issue if you created a table like so using create_join_table

   create_join_table :cocktails, :ingredients, table_name: :portions do |t|
      t.index :cocktail_id
      t.index :ingredient_id

      t.string :measurement, null: false
    end

And in the models use

has_many :ingredients, through: :portions
has_many :cocktails, through: :portions

Or

has_and_belongs_to_many :cocktails, join_table: :portions

Administrate will not work. Administrate expects an id on every table and if using create_join_table Rails will not define an id column to the join table (technically is not needed)

PS: I created a dashboard only for the 2 models (Cocktail and Ingredient in this case) and no dashboard for the join model (Portion) and still doesn't work, get an error.

TL;DR: Add an id to your join table if having problems with HABTM relationships

cristianriano avatar Feb 23 '21 08:02 cristianriano

Revisiting this issue. I understand more clearly now. The problem is with visiting the dashboard for the join model Portion, or dashboards that reference it. As correctly pointed out, Administrate assumes that every model will have a single primary key, and will not accept composite keys.

To an extent, this was part of a know limitation of ActiveRecord, which was known not to handle composite keys. However this is starting to change currently (eg: see https://github.com/rails/rails/pull/47720), so we may be able to allow it in the near future.

pablobm avatar Apr 06 '23 16:04 pablobm