ActiveRecord Generators: supporting custom foreign key column name

Hi! Looking for a good first task to try my hand at contributing to Rails. I was curious to see if anyone else thought this would be a good idea:

Tweaking the attribute parsing for the resource/belongs_to branch of the GeneratedAttribute parsing logic to look for a model class name OR a table name. That string is then used as the foreign key in the migration and the class name used in the relation for the generated model. (and just converting between the two as needed) I would need to add a special case for {polymorphic} to keep things working as-is, meaning that polymorphic would be off-limits as a table name.

It feels common enough to have a origin and destination relation that point at the same model, so I feel like it would be a nice little feature for the model/resource/scaffold generators. The end outcome would look like:

rails g model message sender:references{User} recipient:references{User}

or

rails g model message sender:references{users} recipient:references{users}

both resulting in:

# models/message.rb class Message < ApplicationRecord belongs_to :sender, class_name: "User" belongs_to :recipient, class_name: "User" end 
# db/migrate/xxx.rb class CreateMessages < ActiveRecord::Migration[8.0] def change create_table :messages do |t| t.references :sender, null: false, foreign_key: { to_table: 'users' } t.references :recipient, null: false, foreign_key: { to_table: 'users' } t.timestamps end end end 

The only issue I can think of is the fact that the current logic does split up the attributes string and uses that list when building the parsed attributes hash, so it cooooould be risky to restrict that behaviour down to just polymorphic. Someone could be relying on that behaviour for some custom flag.

I had found this other thread from 2018 mentioning something similar, but using a table: prefix in the string. Something like references:{table: users,polymoprhic,anotherflag}. That feels a bit weird to me though, just a bit too verbose for something that feels rather common. Open to using that though if that’s the best way to go!

1 Like

This is a thoughtful proposal and certainly taps into a real-world use case — modeling relationships where multiple associations point to the same table but with different semantics (like sender and recipient). Enhancing rails g model to accept a {ClassName} or {table} hint and generate the appropriate foreign_key: { to_table: ... } and class_name options would streamline boilerplate and improve readability for such cases. The syntax you’re suggesting (references{User} or references{users}) feels intuitive and aligns with Rails’ principle of convention over configuration, while still allowing explicit control when needed.

That said, it’s wise to be cautious about existing behavior — especially if people are using curly-brace flags for other custom logic. It might be worth submitting a draft PR with clear documentation and tests, along with a deprecation warning or fallback for edge cases. Engaging in a discussion on the issue tracker (or creating a new feature flag to gate the behavior) would help gather feedback from the core team and wider community to ensure the change doesn’t unintentionally break developer expectations.

Well… as the robot suggested, I guess I’ll try the issue tracker then to see if anyone has any thoughts about it.

For what it’s worth, just getting the question restated back at me, filtered through an LLM just sort of sucks. It really is just meaningless to post that.

@ahmad54 This is a warning, please do not post auto-generated replies here. I can’t tell based on your previous posts if you’re a bot, with enough confidence, so I’m giving you the benefit of the doubt.

1 Like