STI on resources: always use base class when saving roles on resources#517
STI on resources: always use base class when saving roles on resources#517doits wants to merge 1 commit intoRolifyCommunity:masterfrom
Conversation
b5b9126 to
4a43f60
Compare
|
In my opinion, this should be an optional. A configuration where one can set if using base class or not for STI. |
Do you have a special use case in mind where this is needed or not solvable by other means? Otherwise I'd say following what Rails suggests and expects for polymorphic associations prevents other surprises (emphasis by me):
|
|
I agree with @doits on this one. The default for rails is to save the polymorhpic name when doing something like: Role.create(resource: a_resource_with_sti)Since the type of a resource can change in rails, saving the base class is safer. I think the only argument for making this optional instead of default is for backward compatibility for people already using rolify. |
| def remove(relation, role_name, resource = nil) | ||
| cond = { :name => role_name } | ||
| cond[:resource_type] = (resource.is_a?(Class) ? resource.to_s : resource.class.name) if resource | ||
| cond[:resource_type] = (resource.is_a?(Class) ? Rolify.base_class_for(resource).to_s : Rolify.base_class_for(resource.class).name) if resource |
There was a problem hiding this comment.
I know you didn't write original code, but it is confusing that we do SomeClass.to_s and some_instance.class.name. I figure we should be consistent and do SomeClass.name and some_instance.class.name. 99% of the time to_s and name act the same but I could imagine someone overriding to_s on an AR class and having this break. I also think if you get rid of Rolify.base_class_for this could be simplified with:
(resource.is_a?(Class) ? resource.polymorphic_name : resource.class.polymorphic_name) if resourcehttps://api.rubyonrails.org/classes/ActiveRecord/Inheritance/ClassMethods.html#method-i-polymorphic_name documents this method. It is what should be saved in resource_type without having to find the base class.
There was a problem hiding this comment.
Thank for you fedback @thijsnado! I finally came back to this PR and adapted it to use polymorphic_name, definately simpler like this!
There was a problem hiding this comment.
What do you know, for the first time in a long time, I attacked this problem without paying attention to open PRs, and now in exactly the same timeframe as you commenting on that @doits, I offered my PR on the same thing.
|
To have it in the discussion here, too: I just updated it to be more simpler by using Not sure abouth the migration path for existing users though, who have saved old values in the database already 🤔 |
I had the problem fetching and retrieving roles by passing a resource which was actually a STI sub class:
With this PR it should always call
base_classon the classes, so it always uses thebase_classto fetch and save records, which is in accordance to Rails' docs:ToDo:
resource_type?)