Rails 5: застрял в действии редактирования, обновление не работает

#ruby-on-rails #ruby #views #controllers

#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

def edit
@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 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
 

В /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 %>
 

Когда я открываю /common/roles/1/edit, я вижу это:

 Started GET "/common/roles/1/edit" for 194.8.16.19 at 2016-10-17 13:08:17  0000
Processing by Common::RolesController#edit as HTML
Parameters: {"id"=>"1"}
User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
Role Load (0.5ms)  SELECT  "roles".* FROM "roles" WHERE "roles"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 

Когда я нажимаю кнопку «Сохранить изменения», я вижу это:

 Started GET "/common/roles/1/edit?utf8=✓amp;_method=patchamp;authenticity_token=QoCCvXkM2+77ZyO0npTBKv1PKTQdkFjkLLbIgmdSXN8uli1ElLBfwHD6GXVTA/a65cQPVPCqJNSkF0d8l5SSgw==amp;general=seller_buyeramp;dashboard=editeramp;rights=editeramp;commit=Save changes" for 194.8.16.19 at 2016-10-17 13:10:54  0000
Processing by Common::RolesController#edit as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"QoCCvXkM2 77ZyO0npTBKv1PKTQdkFjkLLbIgmdSXN8uli1ElLBfwHD6GXVTA/a65cQPVPCqJNSkF0d8l5SSgw==", "general"=>"seller_buyer", "dashboard"=>"editer", "rights"=>"editer", "commit"=>"Save changes", "id"=>"1"}
User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
Role Load (0.4ms)  SELECT  "roles".* FROM "roles" WHERE "roles"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 

или вот так:

 --- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  utf8: "✓"
  _method: patch
  authenticity_token: QoCCvXkM2 77ZyO0npTBKv1PKTQdkFjkLLbIgmdSXN8uli1ElLBfwHD6GXVTA/a65cQPVPCqJNSkF0d8l5SSgw==
  general: seller_buyer
  dashboard: editer
  rights: editer
  commit: Save changes
  controller: common/roles
  action: edit
  id: '1'
permitted: false
 

Похоже, что он не передает «роль»=> {… и после токена он показывает параметры, которые я пытаюсь обновить. Насколько я понимаю, это может быть причиной того, почему обновление не происходит.

role routes.rb выглядит так:

  namespace :common do
   resources :companies
   resources :roles
 end
 

Индексирование и редактирование действий для ролей работают, все действия, включая обновление, работают для компаний.

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

Обновление Я могу обновлять роли вручную в консоли без проблем — найдите роль по идентификатору и обновите любой столбец. По-прежнему не повезло с формой — остается в действии редактирования после f.submit .

Обновление 2

Похоже, что все с маршрутами хорошо:

                      common_roles GET    /common/roles(.:format)                          common/roles#index
                                  POST   /common/roles(.:format)                          common/roles#create
                  new_common_role GET    /common/roles/new(.:format)                      common/roles#new
                 edit_common_role GET    /common/roles/:id/edit(.:format)                 common/roles#edit
                      common_role GET    /common/roles/:id(.:format)                      common/roles#show
                                  PATCH  /common/roles/:id(.:format)                      common/roles#update
                                  PUT    /common/roles/:id(.:format)                      common/roles#update
                                  DELETE /common/roles/:id(.:format)                      common/roles#destroy
 

Пока не знаю, почему ошибка все еще происходит… насколько я понимаю, это не из-за неправильных маршрутов.

Обновление 3

Хорошо, я понял, почему действие редактирования застряло — потому что я думал, что не имеет значения, находится ли form_for оно до или после <form class> тега. Похоже, мне пришлось поместить его ПЕРЕД <form class> тегом. Итак, нет, теперь я получаю основную ошибку на экране: param is missing or the value is empty: role есть идеи, почему?

Обновление 4

Хорошо, теперь я выяснил основную проблему. В основном перечисления вообще не обновляются. Поскольку моя форма состоит только из перечислений, она не передается и не обновляется. Теперь я должен выяснить, как мне правильно сохранять / обновлять перечисления. Любой намек приветствуется!

Комментарии:

1. Проблема заключается в методе: form_for следует сгенерировать форму с помощью метода POST (вы должны увидеть «Начал публикацию в […]» при нажатии «Сохранить изменения»)

2. @user3033467 Да, я знаю, однако у меня есть идентичная form_for для «Компаний» (например, /common/companies/1/edit ), и там я могу выполнить обновление без каких-либо проблем. Это меня сильно смущает. Как мне тогда опубликовать, пожалуйста?

3. Вы не должны использовать пробелы между именами ваших методов и их открывающими круглыми скобками. form_for ( должно быть form_for( .

4. @meagar, ок, изменено, но ошибка та же. Я попробовал решение user3033467, но ничего не изменилось — та же старая ошибка, которая у меня была: (

Ответ №1:

form_for ([:common, @role], :html => { method: 'POST' }) должно работать

Комментарии:

1. Это выдало мне эту ошибку: syntax error, unexpected keyword_ensure, expecting end-of-input хотя я поставил `<% end %>’ в конце моей формы.

2. однако никаких изменений — все еще застрял в действии редактирования

3. Хотя этот фрагмент кода может решить проблему, он не объясняет, почему или как он отвечает на вопрос. Пожалуйста, включите объяснение вашего кода , так как это действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос для читателей в будущем, и эти люди могут не знать причин вашего предложения по коду.