我有一个关于为我正在开发的应用程序的特定部分构建 Restful 设计的最佳方式的问题。
应用程序的一些背景:
User has_one :settings_for_email
有一个 profile_controller,它有一个 show action.. 像这样:
def show
@user = current_user
end
最初这是设置,以便表单将回发到配置文件 Controller .. 类似于:
<% form_for profile_path(@user) do |f| %>
<% f.fields_for :settings_for_email do |s| %>
<% ... form fields ... %>
<% end %>
<% end %>
并且 profile_controller 的更新 Action 做了这样的事情:
def update
@user = User.find(params[:id])
@user.settings_for_email.update_attributes(params[:user][:settings_for_email])
end
....
我不喜欢这个,因为它有一个允许更改正在编辑的用户记录的漏洞...将其更改为@user = current_user,对我来说没有多大意义,因为它是一个更新操作,需要一个某种 ID.. 所以去/profile/123 或 profile/456 会产生相同的用户记录(因为它将使用 current_user,params[:id] 将是多余的).. 这对我来说似乎很奇怪。
作为旁注,我需要一个 Controller 操作来将用户的电子邮件设置重置为默认设置。
所以,我最终做的是开辟了一条新路线:
resource :settings_for_email, :only => :create do
post :reset, :on => :member
end
然后创建一个 settings_for_email_controller:
#settings_for_email_controller.rb
def create
current_user.settings_for_email.update_attributes(params[:settings_for_email_controller])
redirect_to profile_url
end
def reset
current_user.reset_settings_for_email!
redirect_to profile_url
end
...
但后来我想知道,这是否可以通过任何方式进行改进?
如果我真的想让这 100% 放松,最好的做法是:
#update_settings_for_email_controller:
def create
current_user.settings_for_email.update_attributes(params[:settings_for_email_controller])
redirect_to profile_url
end
#reset_settings_for_email_controller:
def create
current_user.reset_settings_for_email!
redirect_to profile_url
end
我对此持观望态度,因为为此配备两个 Controller 似乎有点傻……但我想不出更好的方法。同样,使用 update 需要一个 id,destroy 也是如此。我最初认为使用 destroy 操作来执行“重置”会很好,但是——再次……它会涉及一个浪费的 id 参数。所以我想我应该在这里问问你们对这类事情的看法?
最佳答案
我认为您有点搞混了:这里有两个用户。有详细信息需要更改的用户,还有进行实际更改的用户。通常,它们是相同的,但并非总是如此,例如:管理员可能需要重置某些用户的密码。
被更改的用户记录的 ID 应该进入 REST 接口(interface),User.find params[:id]
应该很好地处理它。
进行更改的用户必须进行身份验证(确保该用户是她声称的身份)和授权(是否允许使用该用户进行更改?)。这是您在调用 current_user
时获得的用户。像 devise 这样的 gem 帮助解决这个问题。
一般来说,你的 Controller 操作应该获取current_user
,和目标用户,确保当前用户被授权对目标用户执行操作(因为他们是同一个用户,当前用户是管理员或您应用程序中的任何其他逻辑),然后才执行该操作。
关于ruby-on-rails - Restful 设计的建议?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7102997/