Rails 5, Rolify - удаление роли у пользователя

Я действительно изо всех сил пытаюсь понять что-то фундаментальное для написания кода на рельсах. Я не знаю, что значит задавать более фундаментальный вопрос, но, похоже, у меня неоднократно возникали подобные проблемы.

Мне удалось настроить rolify в моем приложении Rails 5. Я использую rolify для назначения ролей пользователям.

Теперь я пытаюсь настроить функцию удаления ролей у пользователей после их назначения.

В моем пользовательском индексе у меня есть;

<% user.roles.each do |role| %>
  <%= role.name.titleize %> <br>
<% end %>  

Это показывает роли, которые были назначены.

Затем я пытаюсь добавить:

<%= link_to 'Destroy', role, method: :delete, data: { confirm: 'Are you sure?' } %>

Мой метод уничтожения определен в моем контроллере assign_roles. Она имеет:

def destroy

    user = User.find(params[:users])
    # role = AppRole.find(params[:roles])
    assigned_role = user.roles
    # user_roles = user.roles
    # organisation = Organisation.first
    # byebug

    user.remove_role assigned_role.name, @current_user.organisation

    flash[:notice] = "Successfully removed"
    redirect_to action: :index
  end

Маршруты:

resources :users, shallow: true do
    scope module: :users do
      resources :assign_roles
    end

Не существует модели assign_role.rb. Я просто использую контроллер и представление.

Когда я пытаюсь использовать ссылку на роль уничтожения в своем пользовательском индексе, я получаю сообщение об ошибке:

Couldn't find User with 'id'=

Кто-нибудь может увидеть, что мне нужно сделать, чтобы действие assign_roles#destroy заработало?

Мое действие create в контроллере assign_roles работает. Она имеет:

def create
    user = User.find(params[:users])
    role = AppRole.find(params[:roles])
    # organisation = Organisation.first
    @organisation = Organisation.find(@current_user.organisation)
     # byebug

    user.add_role role.display_name, organisation

    flash[:notice] = "Successfully created"
    redirect_to action: :index
  end

Контроллер назначения ролей целиком:

class Users::AssignRolesController < ApplicationController

  before_action :authenticate_user!

  def index
    # if @current_user.is_admin?
      @app_roles = AppRole.all
    # else
    #   @app_roles = AppRole.where(category: relevant_category)
    # end

    # if @current_user.is_admin?
        @users = User.all
   #  else 
      #   @users = current_user.organisation.users.select { |u| u.id != current_user.organisation.owner_id }
    # end  
  end


  def create
    user = User.find(params[:users])
    role = AppRole.find(params[:roles])
    # organisation = Organisation.first
    @organisation = Organisation.find(@current_user.organisation)
     # byebug

    user.add_role role.display_name, organisation

    flash[:notice] = "Successfully created"
    redirect_to action: :index
  end

  def show
    # @users = User.joins(:profiles).where('profiles.organisation_id = ?' @current_user.organisation.id)
    # @users = User.all
    @current_user.organisation.users
  end

  def update
  end

  def destroy

    user = User.find(params[:users])
    # role = AppRole.find(params[:roles])
    assigned_role = user.roles
    # user_roles = user.roles
    # organisation = Organisation.first
    # byebug

    user.remove_role assigned_role.name, @current_user.organisation

    flash[:notice] = "Successfully created"
    redirect_to action: :index
  end

end

Я МОГУ ДЕЛАТЬ ТО, ЧТО ХОЧУ, ИЗ КОНСОЛИ — Я НЕ ПОНИМАЮ, КАК ЭТО СДЕЛАТЬ ИЗ КОДА

В консоли могу написать:

u.remove_role :fff, Organisation.first

Это затем успешно удаляет роль.

Это нормально для теста, но в коде я пытаюсь использовать current_user.organisation вместо Organization.first. Моя цель — позволить пользователю управлять ролями только в своей организации.

В моем контроллере назначения ролей у меня есть действие уничтожения, скопированное выше.

В моем индексе пользователей у меня есть попытка удалить назначенную роль от пользователя как:

 <% user.roles.each do |role| %>
              <table class="table table-bordered">
              <tr>
                <td><%= role.name.titleize %></td>
                <td><%= link_to 'Remove role', role,  method: :delete, data: { confirm: 'Are you sure?' } %></td>

Ошибка говорит:

undefined method `role_path' for #<#

Интересно, нужно ли мне указать что-то еще в пути, чтобы он мог найти действие assign roles#destroy?

Когда разгребаю маршруты | grep assign, я вижу:

 DELETE   /assign_roles/:id(.:format)                                             users/assign_roles#destroy

Я попытался изменить путь в моем пользовательском индексе на:

<% user.roles.each do |role| %>
              <table class="table table-bordered">
              <tr>
                <td><%= role.name.titleize %></td>
                <td><%= link_to 'Remove role', assign_role_path(user),  method: :delete, data: { confirm: 'Are you sure?' } %></td>
              </tr>  
              </table>
             <% end %>

Но тогда это дает эту ошибку:

Couldn't find User with 'id'=

Я не понимаю, что означает эта ошибка.

Еще одна подсказка

Правильно, чтобы я мог видеть, где возникает проблема. У меня нет идей, как это исправить.

В консоли я могу успешно удалить роль пользователя так, как хочу, выполнив следующие действия:

u.remove_role :sdfddd, Organisation.first
  Organisation Load (2.0ms)  SELECT  "organisations".* FROM "organisations" ORDER BY "organisations"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Role Load (0.7ms)  SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND "roles"."name" = $2 AND "roles"."resource_type" = $3 AND "roles"."resource_id" = $4  [["user_id", 4], ["name", "sdfddd"], ["resource_type", "Organisation"], ["resource_id", 1]]
   (0.1ms)  BEGIN
  SQL (0.4ms)  DELETE FROM "users_roles" WHERE "users_roles"."user_id" = $1 AND "users_roles"."role_id" = 6  [["user_id", 4]]
   (1.6ms)  COMMIT

В коде мое текущее действие уничтожения из контроллера назначения ролей, в котором говорится:

def destroy

    # user = User.find(params[:users])
    user = User.find(params[:id])
    # role = AppRole.find(params[:roles])
    assigned_role = user.roles
    # user_roles = user.roles
    organisation = Organisation.first
    # organisation = Organisation.find(current_user.organisation)

    # byebug

    user.remove_role assigned_role.name, organisation

    flash[:notice] = "Successfully created"
    redirect_to root_path
  end

показывает этот процесс в журнале:

User Load (1.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 4], ["LIMIT", 1]]
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 4], ["LIMIT", 1]]
  Organisation Load (0.7ms)  SELECT  "organisations".* FROM "organisations" ORDER BY "organisations"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Role Load (1.0ms)  SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND "roles"."name" = $2 AND "roles"."resource_type" = $3 AND "roles"."resource_id" = $4  [["user_id", 4], ["name", "Role"], ["resource_type", "Organisation"], ["resource_id", 1]]

Второй параметр — это «Роль», где, возможно, это должно быть имя роли (я думаю). Роль — это имя таблицы.

Я не уверен, как подключить это, чтобы заставить это работать. Может ли кто-нибудь увидеть, как я могу заставить код обрабатываться так, как я могу сделать это в консоли?

СЛЕДУЮЩАЯ ПОПЫТКА

Моя новая попытка уничтожить действие в контроллере assign_roles имеет:

def destroy

    # user = User.find(params[:users])
    user = User.find(params[:id])
    # role = AppRole.find(params[:roles])
    assigned_role = user.roles
    # user_roles = user.roles
    # organisation = Organisation.first
    organisation = Organisation.find(current_user.organisation)

    # byebug

    user.remove_role assigned_role, organisation

    flash[:notice] = "Successfully created"
    redirect_to root_path
  end

Я думаю, что проблемная строка заключается в следующем:

assigned_role = user.roles

Это должна быть конкретная роль, которую я пытаюсь уничтожить (из массива назначенных ролей пользователя).

Журнал показывает:

[["user_id", 4], ["name", "#<Role::ActiveRecord_Associations_CollectionProxy:0x007f887ddb9c98>"], ["resource_type", "Organisation"], ["resource_id", 1]]

Роль не должна быть массивом. Это должна быть конкретная роль. Итак, мое следующее предположение — попробовать добавить роль в ссылку в моем пользовательском индексе, которая сейчас выглядит так:

<%= link_to 'Remove role', assign_role_path(user, role),  method: :delete, data: { confirm: 'Are you sure?' } %>

Затем мне нужны идеи о том, как я могу переписать строкуassign_role в своем действии уничтожения, чтобы она знала, какую роль я пытаюсь отменить для пользователя.

У меня нет хороших идей, как это сделать.

# role = AppRole.find(params[:roles])
assigned_role = user.role
# user_roles = user.roles

Любые идеи, которые могли бы помочь продвинуть эту мысль вперед?


person Mel    schedule 25.10.2016    source источник
comment
не могли бы вы показать index метод?   -  person idej    schedule 08.11.2016
comment
что показывает лог?   -  person Marcus    schedule 08.11.2016
comment
Непосредственно перед user = User.find(params[:users]) напечатайте хэш ваших параметров через puts params. Я предполагаю, что вы должны использовать user = User.find(params[:id]) или user = User.find(params[:user_id])   -  person Magnuss    schedule 08.11.2016
comment
Я не могу установить другую награду, чтобы попытаться найти помощь с этим, пока не заработаю еще несколько очков. Тем временем я буду продолжать публиковать свои попытки и надеюсь, что наткнусь на решение.   -  person Mel    schedule 16.11.2016


Ответы (1)


Вы хотите уничтожить роль только для одного пользователя, верно? Так

params[:users]

не должно быть множественного числа, и :users не является допустимым ключом для параметров.

Вы в основном пытаетесь

User.find(nil)

который терпит неудачу с

ActiveRecord::RecordNotFound: Couldn't find User with 'id'=

Вы, вероятно, должны использовать

User.find(params[:id])
person Eric Duminil    schedule 08.11.2016
comment
Привет Эрик. Нет, я хочу удалить роль пользователя. Я могу назначать роли с помощью действия создания ролей. Я сейчас ищу, как удалить назначенные роли у пользователей (не самого пользователя) - person Mel; 09.11.2016
comment
Отредактировано, спасибо. У вас есть полное сообщение об ошибке и трассировка? В какой строке ваш код вызывает исключение? Couldn't find User with 'id'= будет означать, что ваш код не может даже попытаться удалить роль. params[:users] по-прежнему выглядит необычно для Rails. - person Eric Duminil; 09.11.2016