3

我的rails应用程序中有以下路线

match '/settings', to: 'Users#edit', as: 'settings'

以及对应的控制器代码

def edit
  @user = current_user
end

def update
  correct_user
  @user = User.find(params[:id])
  if !@user.authenticate(params[:old_password])
    flash[:error] = 'Old password did not match'
    redirect_to settings_path
  elsif @user.update_attributes(params[:user])
    flash[:success] = "Settings updated"
    redirect_to settings_path
  else
    render 'edit'
  end
end

我的编辑页面现在只是一个密码更改页面,当我访问时,/settings我看到了我想要排除的页面。当 Iredirect_to settings_path时, url 仍然存在/settings,这是我想要的行为。

在我的edit模板中,我有代码来处理对象错误并将它们呈现在页面上。时render 'edit,如果存在对象错误,则触发此代码。但是,如果我重定向到该页面,则代码不存在。所以我需要打电话render 'edit'查看错误。

但是,调用render 'edit'会导致 URL 更改为/users/:id/edit,这正是我想要的。我希望 URL/settings在调用后保留render 'edit'。我怎样才能做到这一点?

注意:我已经搜索过 SO 和互联网的其他部分,但没有找到适合我需要的内容。有一两个类似问题的 SO 主题,但它们都使用闪烁和 hacky 基于重定向的解决方法,这不是我想要的。

4

2 回答 2

6

您可能希望像这样设置您的路线:

match 'settings': 'users#edit', via: :get
match 'settings': 'users#update', via: :put

然后应该像这样声明表单:

<%= form_for @user, url: settings_path %>

在你的控制器中,确保你是这样调用render的:

render action: "edit"
于 2012-07-13T20:16:42.607 回答
1

您可能有一个不好link_to的看法,即分别使用旧样式:controller:action参数而不是使用settings_path.

请记住,如果有两个路由到同一个控制器和操作对,则定义的第一个路由具有优先级。首先定义您的自定义路由以确保默认使用它。

于 2012-07-13T20:15:09.440 回答