Make just one restful action singular

Can we make just one restful action singular?

Here's my situation.

I have a user model. Hence:
[code]
ActionController::Routing::Routes.draw do |map|
  ...
  map.resources :users
  ...
end
[/code]

But now the problem is whenever a user wants to edit his profile the
corresponding path for this job will be /users/:id/edit . Now it's
needless to say that using this mechanism is not at all secure since the
:id can be changed by the user in the url. That would save those changes
in some other user's record. However that is not the issue here since
that has been taken care of in:

[code]
def edit
@user = current_user
end
[/code]

So now generating /users/:id/edit is futile. How can I generate
/users/edit ??? However I want to keep it restful.

Regards,

Utsav

Utsav Gupta wrote:

Can we make just one restful action singular?

Here's my situation.

I have a user model. Hence:
[code]
ActionController::Routing::Routes.draw do |map|
  ...
  map.resources :users
  ...
end
[/code]

But now the problem is whenever a user wants to edit his profile the
corresponding path for this job will be /users/:id/edit . Now it's
needless to say that using this mechanism is not at all secure since the
:id can be changed by the user in the url. That would save those changes
in some other user's record.

You mean you don't have a permissions system in place?

However that is not the issue here since
that has been taken care of in:

[code]
def edit
@user = current_user
end
[/code]

So now generating /users/:id/edit is futile. How can I generate
/users/edit ??? However I want to keep it restful.

/users/edit would seem like it's supposed to edit *all* users. You
probably want something like /user/edit .

Best,

<snip>

/users/edit would seem like it's supposed to edit *all* users. You
probably want something like /user/edit .

<snip>

Sorry, going to commit the sin of not answering your question directly :slight_smile:

Would an approach such as this not make your interface less clear?

Within the Rails interpretation of REST, a path such as user/edit would still make it seem as if you are working on a collection rather than a member.

While users/1234/edit may be redundant because your code is taking care of determining the user, the consumer of this interface should not need to know about this. Even if it is redundant, I would say the clarity that you achieve by using users/:id/edit outweighs the cost of the duplication.

Perhaps an approach would be to return a 403 if the consumer tries to edit a user that is not a current user?

Rory McKinley wrote:

<snip>

Wrong. If that were so, map.resource wouldn't exist.

<snip>

I think I explained myself badly - I am not arguing that you cannot do it - but I was stating that for a consumer of the user/edit resource - the consumer needs to know internal detail (that the user will be set to the current user) to be able to answer the question "Which user am I editing?".

With the more explicit version - users/:id/edit - it is more obvious which resource is being edited.

So, whichever one is better depends on the OP's use case and how much he wants the consumer to know about the implementation. I tend to err on the side of more explicitness with methods that are publicly exposed but I am always open to hearing counter opinions on the matter :slight_smile:

Can't you declare the resource in the singular form?

http://api.rubyonrails.org/classes/ActionController/Resources.html#M000308