Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Derive foreign key from model name in has_many associations #42215

Merged
merged 1 commit into from
May 12, 2021

Conversation

volmer
Copy link
Contributor

@volmer volmer commented May 12, 2021

Currently Active Record derives the foreign key name for has_many associations based on the Active Record Base `name. Sometimes when using additional conventions for class names, such as with class name suffixes and prefixes, it makes sense to be able to further customize the foreign key logic to account for a different pattern.

Similar to what was done in the case of table names, as Active Record Base extends Active Model Naming, we have already a model_name at the class-level that behaves similarly to name while at the same time giving more flexibility by allowing specifying a custom name and namespacing.

This commit changes the foreign key computation in Reflections to infer its value based on the Active Record's model_name object instead of its class name. This allows customization of the foreign key pattern since a distinct instance of ActiveModel::Name can be used instead.

For example, to use post_id as foreign key for a PostRecord class in a has_many association:

 class PostRecord < ActiveRecord::Base
   has_many :comments

   class << self
     def model_name
       ActiveModel::Name.new(self, nil, "Post")
     end
   end
 end

 PostRecord.reflect_on_association(:comments).foreign_key
 # => "post_id"

Currently Active Record derives the foreign key name for `has_many`
associations based on the Active Record Base `name. Sometimes when using
additional conventions for class names, such as with class name suffixes
and prefixes, it makes sense to be able to further customize the
foreign key logic to account for a different pattern.

Similar to what was done in the
[case of table names](#42213),
as Active Record Base extends Active Model Naming, we have already a
`model_name` at the class-level that behaves similarly to `name` while
at the same time giving more flexibility by allowing specifying a custom
name and namespacing.

This commit changes the foreign key computation in Reflections to infer
its value based on the Active Record's `model_name` object instead of
its class `name`. This allows customization of the foreing key pattern
since a distinct instance of `ActiveModel::Name` can be used instead.

For example, to use `post_id` as foreign key for a `PostRecord` class
in a `has_many` association:

```ruby
 class PostRecord < ActiveRecord::Base
   has_many :comments

   class << self
     def model_name
       ActiveModel::Name.new(self, nil, "Post")
     end
   end
 end

 PostRecord.reflect_on_association(:comments).foreign_key
 # => "post_id"
```
@rafaelfranca rafaelfranca merged commit e72d990 into rails:main May 12, 2021
@volmer volmer deleted the foreign-key-from-model-name branch May 12, 2021 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants