Первый аргумент в форме не может содержать nil или быть пустым в rails 4.0

Их множество, особенно для Rails 4.0 и Rails 3.x. Я новичок во вложенной маршрутизации, и мне это очень сложно, особенно с формами.

Итак, у меня есть следующее:

Маршруты

  resources :users do
    resources :api_keys, path: '/developmentcenter'
  end

Связь здесь следующая: у пользователя много ключей API, где ключ API принадлежит пользователю.

Контроллер

class ApiKeysController < ApplicationController
  before_action :authenticate_user!

  def new
    @user = User.find(params[:user_id])
    @api_key = ApiKey.new(:user => @user)
  end

  def index
    @user = User.find(params[:user_id])
    @api_key = @user.api_keys
  end

  def create
    @user = User.find(params[:user_id])
    @api_key = ApiKey.new(create_new_api_key)
    create_api_key(@api_key, @user)
  end

  def destroy
    @user = User.find(params[:user_id])
    destroy_api_key(@user)
  end

  private

  def create_new_api_key
    params.permit(:api_key, user_attributes: [:id])
  end
end

Вышеизложенное довольно просто. create_api_key — это метод, который делает что-то при сохранении или делает что-то еще при неудачном сохранении. В то время как destroy_api_key Просто найдите ключ API на основе идентификатора пользователя и удалите его, что-то сделает в случае успеха и что-то в случае неудачи.

Итак, теперь давайте создадим форму, которая имеет одну кнопку для создания ключа API.

<h2>Create a new Key</h2>
<%= form_for ([@user, @api_keys]) do |f| %>
  <p class="button"><%= f.submit "Generate API Key" %></p>
<% end %>

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

Но подождите, у нас есть ошибка:

First argument in form cannot contain nil or be empty

Эта ошибка возникает по адресу:

 <%= form_for ([@user, @api_keys]) do |f| %>

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

Я не могу понять это.


person TheWebs    schedule 14.12.2013    source источник


Ответы (1)


Он сообщает вам, что @user пуст или равен нулю в контексте, который он использует. Либо это пользователь, который еще не был создан в БД, либо ваш вызов User.find не работает, чтобы вернуть фактического пользователя. Форма должна знать, кто такой @user, прежде чем она сможет создать для него вложенный ресурс (@api_key). Ваш `create_api_key' совершенно неверен. Сначала вам нужно внести в белый список свои параметры, затем найти пользователя в БД (или создать их), затем вы можете использовать переменную экземпляра @user, чтобы создать форму для этого пользователя для создания ключа. Я думаю, что если вы сделаете это правильно, вам не нужно будет вызывать @api_keys в начале формы, если вы определили отношения в своих моделях (has_many или has_one, own_to и т. д.). Можете ли вы опубликовать вывод консоли веб-сервера при посещении этой страницы? Сначала вы звоните

 @user = User.find(params[:user_id])

каждый раз в вашем контроллере. Вы должны высушить это с помощью before_action.

private
def set_user
  @user = User.find(api_key_params[:user_id])
end

Тогда в верхней части контроллера у вас будет:

class ApiKeysController < ApplicationController
  before_action :authenticate_user!
  before_action: :set_user

Также вы должны сделать свой .permit методом, который возвращает переменную с именем api_key_params:

def api_key_params
  params.require(:user).permit(:api_key)
end

Таким образом, у вас есть вещи, которые вы хотите вернуть в белый список. Чтобы получить доступ к этим параметрам, вы просто вызываете метод. Вы можете указать параметр, который вы хотите вернуть из метода, как в моем примере set_user. Но это также дает вам возможность делать такие вещи, как:

def create
  @api_key = Api_key.new(api_key_params)
end

Таким образом, Api_key.new получает пользователя и создает ключ. Вы не показываете, как и где вы генерируете сам ключ. Если он создается каким-либо методом, вы должны поместить его в модель для Api_key. Есть некоторые другие вещи в вашем коде, которые сбивают с толку, не видя остальных ваших файлов.

person Beartech    schedule 17.12.2013