【问题标题】:First argument in form cannot contain nil or be empty in rails 4.0表单中的第一个参数不能包含 nil 或在 rails 4.0 中为空
【发布时间】:2013-12-14 18:58:27
【问题描述】:

其中有很多,尤其是 Rails 4.0 和 Rails 3.x。我是嵌套路由的新手,我发现它非常困难,尤其是表单。

所以我有以下内容:

路线

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

这里的关系是:user有很多api key,其中api key属于user

控制器

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只要根据用户id找到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| %>

所以 - 我已经查看了处理这个错误的每一个堆栈问题(大多数),我已经根据一些改变了我的控制器,就像你在上面看到的那样。我什至查看了 rails 手册中的表单助手文档。

我想不通。

【问题讨论】:

    标签: forms ruby-on-rails-4 nested-routes


    【解决方案1】:

    它告诉你 @user 在它使用的上下文中是空的或 nil 。这是尚未在数据库中创建的用户,或者您的 User.find 调用无法返回实际用户。表单需要知道@user 是谁,才能为其创建嵌套资源(@api_key)。您的“create_api_key”完全错误。您需要首先将您的参数列入白名单,然后在数据库中找到用户(或创建它们),然后您可以使用 @user 实例变量为该用户创建表单以创建密钥。我认为如果你做得对,如果你在模型中定义了关系(has_many 或 has_one、belongs_to 等),则不需要在表单的开头调用 @api_keys。您可以在访问该页面时发布 Web 服务器控制台输出吗?首先你打电话给

     @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 的模型中。你的代码还有一些其他的东西会让人困惑,而不会看到你的其余文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多