2016-10-16 10 views
0

私のアプリでは、current_userはcurrent_user企業に所属するユーザのロールを更新する必要があります。私は編集アクションにアクセスすることができますが、特定のユーザーロールに対して適切な選択が表示されますが、私は更新アクションを実行できません - 編集アクションにとどまります。 Rails 5:belongs_toテーブルの更新アクションが動作しない

この

は私が /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 

/コントローラ/共通/ 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では、私はこのている:

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"} 

:私は、 "変更を保存" ボタンを押すと

<%= 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 %> 

、コンソールに私はこれを見ます"role" => {...を通過していないように見え、トークンの後に私が更新しようとしているparamsが表示されます。私はこれが、なぜアップデートが起こっていないのか理解しています。このような

役割routes.rbを見て:役割作品の

namespace :common do 
    resources :companies 
    resources :roles 
end 

インデックスと編集アクション、すべてのアクションは、会社のために働きます。

役割の列挙型が正しく渡されたようですが、最後には更新アクションはありません。それは編集にとどまり、最初からすべてをロードします。 これを修正するにはどうしたらいいですか?何か助けてくれてありがとう!

+0

フラッシュ 'にエラーを送ります[:error] 'あなたは少なくとも、物事が間違っていた可能性がある箇所を特定することができます。私が座っている場所からは、検証が失敗しているようです。 – Makoto

+0

私が見ているのは、編集アクションから更新アクションにはまったく移行しないということです。つまり、更新アクションの 'flash [:error]'には何も表示されません。私の考えは同じです - 何かがバリデーションに間違っているかもしれませんが、私は今 'models/role.rb'のすべてのバリデーションについてコメントしました。潜在的な検証エラーを確認するためのアイデアはありますか? – matiss

+0

@Makotoコンソールで更新しようとしましたが、 'role = role.update_attributes(dashboard:viewer)'を渡すと動作しますが、 'role = role.update_attributes(dashboard:1)'を渡したようです。それは**ではありません。おそらく素朴な質問ですが、それは列挙型の代わりに整数を渡すようにビューを変更しなければならないということですか? – matiss

答えて

0

ドメインを正しくモデリングしないと、ドメインが過度に複雑になっている可能性があります。

ユーザーモデルのロールにenumを使用すると、ユーザーが1つのロールのみを持つことができる非常に単純なソリューションがあれば、完璧に機能します。

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 
+0

さらに、ロールをさまざまな種類のリソースなどにスコープすることもできます。全体的には、より穏やかで複雑でないパターンで、 'Role'モデルをgodクラスに変えることはできません。また、標準crud動詞を意味のある方法で使用できます。付与/取り消し。 https://github.com/RolifyCommunity/rolify – max

+0

ありがとう、私を助けてくれてありがとう。私は、current_userが会社の(多くの)ユーザー(多く)のロールを編集できるときに、シナリオを実装しようとしています。私はアプリケーションのさまざまな部分のアクセスレベルを設定するためにenumを使用しています。あなたは私がまだ上記のあなたの提案を使用できると思いますか? – matiss

+0

はい。その非常に柔軟なパターン。 [rolify](https://github.com/RolifyCommunity/rolify)をチェックしてください。これは、最初からホイールを再開発する必要がないため、これに非常に似ています。 – max

関連する問題