Rails 5:更新操作不适用于belongs_to表

时间:2016-10-16 05:48:15

标签: ruby-on-rails ruby

在我的应用中,current_user需要更新属于current_user公司的用户的角色。我可以进入编辑操作,在适当的位置显示特定用户角色,但我无法执行更新操作 - 它始终保留在编辑操作

这就是我在 /models/role.rb 中所拥有的:

class Role < ApplicationRecord
belongs_to :user, optional: true, inverse_of: :roles
accepts_nested_attributes_for :user

enum general: { seller: 1, buyer: 2, seller_buyer: 3}, _suffix: true
enum dashboard: { denied: 0, viewer: 1, editer: 2, creater: 3, deleter: 4}, _suffix: true
# other columns for roles follow #

/models/user.rb看起来像这样:

#User has roles
  has_many :roles
  has_many :company_user_roles, through: :companies, source: :user_roles
  accepts_nested_attributes_for :roles, reject_if: proc { |attributes| attributes[:name].blank? }

# User has many companies
  has_many :accounts, dependent: :destroy
  has_many :companies, through: :accounts

/controllers/common/roles_controller.rb 中我有:

class Common::RolesController < ApplicationController
 before_action :get_role, only: [:index, :new, :create, :edit]
 before_action :correct_role, only: [:edit]

def edit
if @roles.any? { |role| role.editer_rights? || role.creater_rights? || role.deleter_rights? }
  @editer_creater_deleter = true
else redirect_to errors_path
end
@role = Role.find(params[:id])
end

def update
@role = Role.find(params[:id])
if @role.update_attributes(role_params)
  flash[:success] = "Role updated!"
  redirect_to dashboard_path
else
  render 'edit'
end

private

def get_role #This is working solution
  @roles = current_user.roles
  end

def correct_role #This is working solution checking if current_user is allowed to access particular role for edit
  redirect_to(errors_path) unless current_user.company_user_roles.where(id: params[:id]).exists?
  end

def role_params #at the end ID of user to whom belongs role is stored
  params.require(:role).permit(:general, :dashboard, //..other role table columns..// , :user_id) 
end
end

/views/common/roles/edit.html.erb 中我有:

<%= form_for ([:common, @role]) do |f| %>
  <%= f.select :general, Role.generals.map { |key, value| [key.humanize, key] } %>
  <%= f.select :dashboard, Role.dashboards.map { |key, value| [key.humanize, key] } %>
  <%= f.submit "Save changes" %>
<% end %>

当我按下“保存更改”按钮时,在控制台中我看到:

Started GET "/common/roles/3/edit?utf8=%E2%9C%93&_method=patch&authenticity_token=ZNVu7jiNOQ6RO7uH7Pe5B4%2BZvf3QKCEFOAZUtCWpNj902dmc3gCG2FULXqkWpU2UIgQrr2ccKdS%2B1iPsv7pqJw%3D%3D&general=buyer&dashboard=editer&commit=Save+changes" for 46.109.175.192 at 2016-10-16 05:24:17 +0000
Processing by Common::RolesController#edit as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZNVu7jiNOQ6RO7uH7Pe5B4+Zvf3QKCEFOAZUtCWpNj902dmc3gCG2FULXqkWpU2UIgQrr2ccKdS+1iPsv7pqJw==", "general"=>"buyer", "dashboard"=>"editer", "commit"=>"Save changes", "id"=>"3"}

看起来没有传递“role”=&gt; {... 并且在令牌之后它显示我尝试更新的参数。据我所知,这可能是为什么更新没有发生。

role routes.rb 如下所示:

 namespace :common do
   resources :companies
   resources :roles
 end

角色的索引和编辑操作起作用,所有操作都适用于公司。

看起来角色枚举正确传递,但最后没有更新操作。它保留在编辑中并从一开始就加载所有内容。 如何解决此问题?感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我认为你可能只是因为没有正确建模而过度复杂化。

如果您拥有一个非常简单的解决方案,用户只能拥有一个角色,那么在您的用户模型上使用enum角色是完全没问题的。

class User < ApplicationRecord
  enum role: [:student, :teacher, :other_staff]
end

如果域更加真实和复杂,通常使用的是用户和角色之间标准的多对多关系。

class User
  has_many :user_roles
  has_many :roles, through: :user_roles
end

# This is join table containing roles assigned to users
class UserRole
  belongs_to :user
  belongs_to :role
end

# This is the "master list" of roles
class Role
  has_many :user_roles
  has_many :users, through: :user_roles
end

分配/撤销角色的最简单方法就是通过普通的CRUD控制器为您的用户执行此操作:

<%= form_for( [:admin, @user] ) do |f| %>
  # ...
  <fieldset>
    <%= f.label :roles_ids, 'Roles' %>
    <%= f.collection_check_boxes(:roles_ids, Roles.all, :id, :name) %>
  </fieldset>
<% end %>
class Admin::UsersController < ApplicationController

  def create
    @user = User.create(user_params)
    respond_with @user
  end

  def update
    @user = User.find(params[:id])
    respond_with @user.update(user_params)
  end

  def user_params
    params.require(:user)
          .permit(:foo, :bar, roles_ids: [])
  end
end