Я действительно изо всех сил пытаюсь понять что-то фундаментальное для написания кода на рельсах. Я не знаю, что значит задавать более фундаментальный вопрос, но, похоже, у меня неоднократно возникали подобные проблемы.
Мне удалось настроить 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
Любые идеи, которые могли бы помочь продвинуть эту мысль вперед?
index
метод? - person idej   schedule 08.11.2016user = User.find(params[:users])
напечатайте хэш ваших параметров черезputs params
. Я предполагаю, что вы должны использоватьuser = User.find(params[:id])
илиuser = User.find(params[:user_id])
- person Magnuss   schedule 08.11.2016