切换模型中的单个值,所有这些都来自link_to

时间:2010-09-26 22:07:47

标签: ruby-on-rails rest link-to

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

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

我想知道的是,这可以在一个link_to调用中完成,还是我需要围绕它构建一个表单?我的管理控制器在routes.rb中定义为'resources:admin',rake routes列出了一个PUT操作,其命名路径为'admin',调用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调用update方法中传递了足够的数据,以便我可以只修改该属性。我意识到可以只定义一个名为toggle_admin的方法,只传递ID并对该模型的成员进行操作,但我认为这种方法尽可能的REST,我更感兴趣在学习我可以在这里使用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"}

我想也许我传递的方法不对,它默认为最后一个,但是this page建议您可以使用:method =>设置:confirm,例如作为HTML选项。

所以从根本上说,我的问题是,我是否应该通过link_to这样做一个RESTful非GET调用?我认为Rails会在幕后为我构建一个小小的形式。

this gist中的更多源代码。

1 个答案:

答案 0 :(得分: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处理以表明它不太花哨)。