I want my helpers to generate paths using a superclass instead of the subclasses. Assuming I have Owner and Member that both inherit from User, rails will use the current objects class name when generating paths:
Let’s say current_user is a mod: <%= link_to current_user.name, current_user %> will generate “/mod/:id”. I want to force it to generate “/user/:id” regardless of the subclass.
You could look into overriding what model name returns for those classes, but that seems really far reaching and dangerous. I’d just use the path helper since that best represents what you want to do, which is send an Owner or Member object not to /owners/:id or /members/:id but to /users/:id instead; ergo the verbosity doesn’t seem bad to me, it helps clarify.
As an alternative, you could also define the /owners/:id and /members/:id routes and point them at UsersController; not sure if that’s okay to have the extra routes, but that allows you to keep your shorthand notation, has that map to the expected URL, but lets you DRY the underlying controller class.
I’m using Rails 3.2. And I’m pretty sure you can. Basically, to get a form to post to the right model I need to set it up generically. My initial form was:
= simple_form_for @user do |f|
To make it work I had to change it to this:
= simple_form_for :user, url: user_path(@user) do |f|
To work with link helpers, I added this as resource:
= simple_form_for :user, url: user_path(@user) do |f|
I’m confused, i thought that is what you are trying to avoid? I.e. you don’t want to have to specify user_path(@user), you wanted to just have @user and have it compute the path helper as user_path, instead of owner_path or member_path? In your solution you just put in user_path, which makes your question moot, no?
To work with link helpers, I added this as resource:
Right, I didn’t spell out the code like you did, but this is “As an alternative, you could also define the /owners/:id and /members/:id routes and point them at UsersController”. As a note, with that set of routes defined you should be able to use your original form declaration:
= simple_form_for @user do |f|
Because simple_form_for will eventually do url_for(@user) like link helpers and therefore as long as owners and members are routed it should work.
The reason would be if you didn’t want to expose the urls:
/members/:id
/owners/:id
I.e. with those routes defined if @user is a member with ID 37 then:
link_to ‘click here’, @user # => goes to ‘/members/37’
link_to ‘click here’, user_path(@user) # => goes to ‘/users/37’
So if you just want to be able to do the first line and don’t care about the url, map the routes; if you want to exactly duplicate the second line (i.e. your original code, and what would technically have ‘helpers to generate paths using a superclass instead of the subclasses’) then you could use becomes as such:
link_to ‘click here’, @user.becomes(User) # => goes to ‘/users/37’
However, I personally think the one with user_path is more readable in this case.