Первый аргумент в форме не может содержать ноль или быть пустым, в то время как он не должен быть ноль или пустым - PullRequest
0 голосов
/ 10 октября 2018

У меня проблема, из-за которой «новые», а иногда и «редактирующие» действия моих контроллеров выдают:

First argument in form cannot contain nil or be empty

Хотя я на 100% уверен, чтоПервый аргумент не ноль и не пустой.Чтобы отточить это, я буду спрашивать только о 'новом' действии, поскольку ресурс просто установлен на Resource.new

permissions / new.haml

= form_for @permission do |f|
  = f.label :name, class: 'form-control-label'
  = f.text_field :name, class: 'form-control'

permissions_controller.rb

class PermissionsController < ApplicationController
  before_action :set_permission, only: [:show, :edit, :update, :destroy]

  def new
    @permission = Permission.new
  end

  def show
    @modules = Modules.all
  end

  def index
    // handling content with api calls instead
  end

  ...
end

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

Я могу воспроизвести эту проблему, перейдя к 'покажите 'действие того же контроллера, затем вернитесь к действию' index 'и затем перейдите к действию' new '.На этом этапе «новая» страница больше не работает, пока я не отредактирую файл контроллера или не перезапущу сервер.

После смены контроллера (добавление пробела в конце) или перезапуска сервера он неожиданно снова работает.

Это не единственный ресурс, с которым это происходит.Часто другие ресурсы, такие как Пользователь, имеют такую ​​же проблему.У меня было несколько проектов, у которых была та же самая проблема, которая так или иначе исчезла, таким образом, я никогда не удосужился исследовать больше об этом.

Версия Ruby: 2.3.5p376

Версия Rails: 5.1.4

edit:

Я заметил, что больше не могу воспроизвести его, еслиЯ закомментирую Modules.all.

modules - это не класс activerecord, это вспомогательный класс для меня, чтобы считать различные файлы в моих каталогах, может ли это чтение вызвать проблемы?

modules.rb

class Modules
  def self.all
    controllers = Dir.glob("#{Rails.root}/app/controllers/**/*.rb").
      map{ |e|
        if e.include?('/api/')
          e.match(/api\/[^\/]*\/[^\/]*.rb/)[0].gsub('.rb', '').gsub('/', '::_').camelcase
        else
          e.match(/[^\/]*.rb/)[0].gsub('.rb', '').camelcase
        end
      }
    modules = {}
    controllers.each do |e|
      c = Object.const_get e
      modules[e.gsub(':','').gsub('Controller', '').underscore] = get_actions_for c if
        !no_permission_needed_for e and c.action_methods.size > 0
    end

    return modules
  end

  def self.get_actions_for(controller)
    actions = controller.action_methods
    grouped_actions.each do |key, value|
      actions.delete(key)
    end

    return actions
  end

  def self.grouped_actions
    {"new" => "create", "edit" => "update"}
  end

end

edit:

Я заметил, что я пытаюсь вызвать actions.delete(key), где actions - это Set строк, где key - этоString

Когда я выполняю actions = controller.action_methods.to_a и принудительно устанавливаю набор в массив, моя проблема, похоже, исчезает.По крайней мере, я не могу больше это воспроизводить.Теперь мне интересно, есть ли что-то, что в корне пошло не так в ruby, где удаление чего-то из Set делает странные вещи под капотом.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Мне кажется, я понял это.

Что я заметил, так это то, что в modules.rb я загружаю действия внутри контроллера через controller.action_methods.после этого я удаляю действия new и edit.

Я предполагал, что просто получаю набор строк, содержащих имена действий вместо реальных действий.Поэтому кажется логичным, что если я удалю действия new и edit, мои представления по умолчанию будут выполнять действия new и edit в ActionController :: Base.Это означало бы, что @permission не установлен, и представление выдает вполне заслуженную ошибку.

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

Итак, я исправил свою проблему, выполнив controller.action_methods.to_a, что вызывает разъединение фактических действий в контроллере.После этого я могу удалить строки в этом массиве, которые мне не нужны.

Мораль истории: следите за controller.action_methods?

0 голосов
/ 10 октября 2018

Один способ, которым это будет работать, но не рекомендуется - это инициализация экземпляра Permission внутри формы:

<%= form_for Permission.new do |f| %>

Проверьте, действительно ли представление, содержащее вашу форму, действительнобудучи обработанным действием new вашего PermissionsController.

...