thoughtbot / administrate

A Rails engine that helps you put together a super-flexible admin dashboard.
http://administrate-demo.herokuapp.com
MIT License
5.9k stars 1.13k forks source link

Models with relationships through join tables not supported #1885

Open cristianriano opened 3 years ago

cristianriano commented 3 years ago

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

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

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

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?

pablobm commented 3 years ago

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?

cristianriano commented 3 years ago

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

pablobm commented 3 years ago

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.

wflanagan commented 3 years ago

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.

cristianriano commented 3 years ago

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

pablobm commented 1 year ago

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.