【问题标题】:Trying to POST to database with Simple Form and Rails尝试使用简单表单和 Rails 发布到数据库
【发布时间】:2021-08-14 02:44:45
【问题描述】:

尝试使用带有 Rails 的简单表单 gem 来 POST 到我的数据库 (postgresql)。我关注了一些视频,但我不完全确定出了什么问题。在我创建发布方法之前,我的表单工作(显然没有做任何事情)。

这是我得到的错误。

我马上就想到了路线问题。但是我的裂缝已经有一段时间了,无法修复。

undefined method `client_assets_path' for #<ActionView::Base:0x0000000000ccd8>
Did you mean?  clients_new_path

这是我的repo,如果它对模型有帮助的话。

这是我的表格:

<%= simple_form_for @clients do |f| %>
        <div class="form-inputs">
            <%# Home %>
            <%= f.input :ppor %>
            <br>
        </div>

        <div class="form-actions">
            <%= f.button :submit %>
        </div>
    <% end %

这是我在客户端控制器中的方法:

class ClientController < ApplicationController
  def index
    @clients = ClientAsset.all
  end

  def new
    @clients = ClientAsset.new
  end

  def create
    @clients = ClientAsset.new(client_asset_params)
    if @clients.save
      redirect_to @clients
    else
      render :new
    end
  end

  private
  def client_asset_params
    params.require(:id).permit(:ppor)
  end
end

这是我的路线:

Rails.application.routes.draw do

  devise_for :admins
  root to: "planner#index"

  get "/index", to: "planner#index", as: :index

  get "/howto", to: "planner#howto", as: :howto

  get "/products", to: "planner#products", as: :products

  get "/planners", to: "planner#planners", as: :planners

  get "/admins/sign_in", to: "admin#sign_in", as: :sign_in

  get "/admins/sign_up", to: "admin#sign_up", as: :sign_up

  devise_scope :admin do
    get "/admins/sign_out" => "devise/sessions#destroy"
  end

  get "/admins/password/edit", to: "devise/password#edit", as: :edit

  get "/dashboard", to: "client#dashboard", as: :dashboard

  get "clients/new", to: "client#new"

end

【问题讨论】:

    标签: ruby-on-rails devise simple-form


    【解决方案1】:

    您有路由问题的直觉是正确的。

    像您这样的表单上的标准/默认行为是 POST 到指定资源的“索引路径”(在您的情况下为/clients)。但是,您尚未定义 POST 路由。

    您收到未定义方法错误而不是“无路由”错误的原因是 simple_form_for 假定您的路由具有“class_name_path”形式的“命名路径助手”这将为它提供适当的目标 URI。由于您没有定义路由,simple_form 找不到关联的方法,您会收到缺少方法的错误。

    因此,您至少需要:

    get "/clients/new", to: "client#new"
    post "/clients", to: "client#create", as: 'client_assets'
    

    as: 选项是必需的,因为默认情况下,Rails 使用资源路径名称 (clients) 创建帮助程序,但 simple_form_for 假定该资源路径是从模型名称 (client_assets) 派生的。

    顺便说一句,当您遵守约定时,Rails 工作得最好、最简单。如果您是 Rails 新手,使用诸如 resourceful routing 之类的东西以及模型和控制器的命名约定(例如,ClientAsset (model) ClientAssetsController (controller))可以让您的 Rails 体验更加流畅。

    【讨论】:

      【解决方案2】:

      您正在发生一些可能导致问题的事情。您在控制器中缺少一条到您的 create 方法的路线。 HTTP 动词应该是 POST。但这可能无法解决您的问题。我会尽力帮助您指明正确的方向。

      我在您的路线文件中注意到了一些东西,我想尝试帮助您引导您走上宁静的道路。大多数 Rails 开发人员会回避创建如下路线:

      get "clients/new", to: "client#new"

      Rails 非常棒,可以为您处理这个问题。我会删除它并将其添加到您的路线文件中:

      resource :clients

      这将自动提供所有需要的路线。索引、显示、新建、创建和销毁。

      将其添加到您的路由文件后,在您的 shell(从项目目录)中运行它rails routes

      你应该注意到你拥有我之前提到的所有路线。

      我想指出的第二件事是你的控制器。控制器的类名是复数形式。模型名称是单数。

      class ClientController &lt; ApplicationController

      正常的 Rails 约定是:

      class ClientsController &lt; ApplicationController

      我想指出的第三件事是:

      def new
        @clients = ClientAsset.new
      end
      

      看看你的回购,我可以告诉你这是不对的。您不应该在 Client 控制器中实例化 ClientAsset 实例。

      在客户端控制器中,我希望看到如下内容:

      def new
        @client = Client.new
      end
      

      在表单中使用 @client 永远不会起作用,它将寻找完全不同的路由和控制器。

      TBH,有很多内容需要考虑。如果您愿意,我可以在您的仓库中发送 PR,如果您有兴趣,可以帮助您重回正轨。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-24
        • 1970-01-01
        相关资源
        最近更新 更多