如何在Rails中正确创建自定义操作?

时间:2013-02-22 18:17:35

标签: ruby-on-rails ruby-on-rails-3 rails-activerecord

我正在尝试创建自定义表单,允许管理员打开和关闭用户的用户权限,并将其保存到数据库中。我必须做一些完全错误的事情,因为页面生成正常,并且提交按钮提交到操作正常,但没有任何内容保存到数据库,它只是再次呈现我的初始视图。谁能看到我做错了什么?

守则

路线:

resources :users do
  member do
    get 'assign'
    put 'assign_update'
  end
end
...

控制器(这种奇怪的做法是试图绕过管理员和其他属性无法访问的事实。这可能是一团糟。):

...
def assign
  @user = User.find(params[:id])
end

def assign_update
  admin_protected = params[:user].delete(:admin)

  @user = User.find(params[:id])
  @user.admin = admin_protected

  if @user.save
    flash[:success] = "User updated"
    redirect_to users_path
  else
    render 'assign'
  end
end

查看:

...
<%= form_for(@user, url: { controller: 'users', 
  action: 'assign_update'}, method: 'put') do |f| %>
  <%= f.label :admin, 'Is admin?', class: 'checkbox inline' %>
  <%= f.check_box :admin %>
  <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
<% end %>

2 个答案:

答案 0 :(得分:1)

总结一下我们在问题评论部分的对话......

发现问题是对其他用户模型属性的验证。无法保存用户实例,因为在执行save方法时未通过验证。因此,Rails只是渲染分配视图。

update_attribute方法更新没有模型验证或质量分配保护的属性。在这种情况下,admin属性符合这两个标准。

答案 1 :(得分:0)

您应该在模型中使用attr_accessible并手动从params中选择这些字段并单独分配它们,以确保管理字段不包含在分配给attr_accessible声明的字段列表中

所以

def assign_update
  admin_protected = params[:user].delete(:admin)

  @user = User.find(params[:id])
  @user.admin = admin_protected

  if @user.save
    flash[:success] = "User updated"
    redirect_to users_path
  else
    render 'assign'
  end
end

变为

    def assign_update
#      admin_protected = params[:user].delete(:admin)

      @user = User.find(params[:id])
      @user.admin = params[:user][:admin]

      if @user.save
        flash[:success] = "User updated"
        redirect_to users_path
      else
        render 'assign'
      end
    end

问题是,在你的方法中,你仍然是大规模分配。

要调试实际发生的事情,您应该仔细查看日志文件输出

<强>更新

检查错误列表。 将以下内容添加到表单

  <% if @user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@user.errors.count, "error") %> prohibited this account from being saved:</h2>

      <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

它应该为您提供广告,让您的用户更清楚地了解错误以及如何解决问题

相关问题