1

我有一个 Rails 3 应用程序页面的管理控制器,它列出了表中的所有用户模型帐户,并且每行的一部分应该是一个链接(带有确认)来切换我的用户模型的 is_admin 属性。我想通过允许管理员单击列出当前管理员状态的表格单元格中的文本来做到这一点(即单击“否”会将 is_admin 设置为 true)。

目前,我对任何花哨的 AJAX 方法不感兴趣,让我们忽略这样一个事实,即从 UI 的角度来看,单击指示对象状态的文本来切换该状态不一定是最佳选择。

我想知道的是,这可以在单个 link_to 调用中完成,还是我需要围绕它构建一个表单?我的管理控制器在 routes.rb 中定义为“资源:admin”,并rake routes列出了一个名为“admin”的 PUT 操作,该操作调用了 admin#update 方法。

这是我到目前为止所得到的:

<%= link_to (user.is_admin ?  "Yes" : "No"), 
             admin_path(:user => {:id => user.id, :is_admin => !user.is_admin}), 
             {:confirm => "Are you sure?", :method => :put} %>

我的想法是我在对更新方法的 RESTful 调用中传递了足够的数据,以便我可以只修改该属性。我意识到可以只定义一个名为 的方法toggle_admin,只传递 ID 并对模型的该成员进行操作,但我认为这种方法尽可能 RESTful,而且我更感兴趣的是了解我可以在这里使用 link_to 。

我得到的错误是:

No route matches {:action=>"destroy", :controller=>"admin", :user=>{:id=>1, :is_admin=>false}}

我不确定它为什么要尝试调用 destroy 方法,这似乎是我的管理员特定路由列表中的最后一件事:

rake routes | grep admin
            site_admin        /admin(.:format)                {:controller=>"admin", :action=>"index"}
           admin_index GET    /admin(.:format)                {:action=>"index", :controller=>"admin"}
           admin_index POST   /admin(.:format)                {:action=>"create", :controller=>"admin"}
             new_admin GET    /admin/new(.:format)            {:action=>"new", :controller=>"admin"}
            edit_admin GET    /admin/:id/edit(.:format)       {:action=>"edit", :controller=>"admin"}
                 admin GET    /admin/:id(.:format)            {:action=>"show", :controller=>"admin"}
                 admin PUT    /admin/:id(.:format)            {:action=>"update", :controller=>"admin"}
                 admin DELETE /admin/:id(.:format)            {:action=>"destroy", :controller=>"admin"}

我想也许我传递了错误的方法并且它默认为最后一个,但是这个页面建议你可以将:method =>你的:confirmeg 设置为 HTML 选项。

所以从根本上说,我的问题是我是否应该能够像这样通过 link_to 进行 RESTful 非 GET 调用?我以为 Rails 只会在幕后为我构建一个小小的迷你表单。

此要点中的更多源代码。

4

1 回答 1

1

用这个:

div_for @user do
  link_to (@user.is_admin? ? "Yes" : "No"), [@user, :toggle], :confirm => ...
end

这条路线:

map.resources :users, :as => "admin", :member => { :toggle => :put }

和这个控制器方法:

class UsersController < ...
  def toggle
    @user = User.find params[:id], :lock => true
    @user.is_admin = !@user.is_admin?
    @user.save!
    if request.xhr?
      render :update {|page| page[@user].replace_html @user }
    else
      redirect_to @user
    end
  end
end

尝试使用更新操作的链接来处理这个问题对于一种情况来说太复杂了(因为您已经发现存在一些陷阱)。在这种情况下使用link_to_remote是一个更好的选择(以防我已经添加了 ajax 处理以表明它不是太花哨)。

于 2010-09-26T23:44:36.507 回答