温馨提示:本文翻译自stackoverflow.com,查看原文请点击:ruby - Namespaced Form Objects in Rails
ruby ruby-on-rails

ruby - Rails中的命名空间表单对象

发布于 2020-04-04 00:11:22

我很难在我正在构建的新的Rails 6项目中设置一些自定义表单对象。我怀疑这可能是由于命名空间问题引起的,但我还不能确定。

app / views / saasy / signups / new.html.erb

<%= form_with(model: [ :saasy, @signup ], url: saasy_signups_path(@signup),  local: true) do |signup_form| %>

  <%= fields_for :account, @signup.account do |account_fields| %>
    Organization name: <%= account_fields.text_field :organization %>
  <% end %>

  <%= signup_form.submit %>
<% end %>

应用程序/控制器/saasy/signups_controller.rb

class Saasy::SignupsController < ApplicationController
  def new
    @signup = Saasy::SignupForm.new
  end

  def create
    @signup = Saasy::SignupForm.new(signup_form_params)
    @signup.register
  end

  private

  def signup_form_params
    params
      .require(:saasy_signup_form)
      .permit(account_attributes: [:organization])
  end
end

config / routes.rb

Rails.application.routes.draw do
  namespace :saasy do
    resources :signups, only: [:new, :create]
  end
end

app / forms / saasy / signup_form.rb

module Saasy
  class SignupForm
    include ActiveModel::Model

    attr_accessor :user, :account

    delegate :attributes=, to: :user, prefix: true
    delegate :attributes=, to: :account, prefix: true

    def initialize(params= {})
      super(params)
      @user = Saasy::User.new(params)
      @account = Saasy::Account.new(params)
    end

    def register
      # eventually do actual signup stuff here
    end

  end
end

但是,无论何时进行测试,我都会收到以下消息:参数丢失或值为空:signup_form

params哈希看起来像这样:

{
"authenticity_token"=>"BhhvRaYKf220afExocQ//LIY1jszVsXs+lThFeUFKvr6ciVBsa+22mSxwO3yT6mK2uOsWSCKx9gL6WIaGmmvSg==", 
"account"=>{"organization"=>"Example Name"}, 
"commit"=>"Create Signup form"
}

我已经尝试了很多解决方案,例如form_with在视图中和更改路线名称等,但是到目前为止我还没有运气。任何建议将不胜感激!

查看更多

提问者
Awire
被浏览
127
max 2020-01-31 20:47

这与名称空间没有任何关系。您只是需要使用错误的参数密钥。

def signup_form_params
  params
    .require(:signup_form)
    .permit(account_attributes: [:organization])
end

Rails通过调用model_name.param_key传递的模型来获取输入的“键” param键不考虑类的模块嵌套。这也不应该是实现细节,也不是您的应用程序通过HTTP公开的“公共api”的必要部分。您的代码组织和应用程序的route / http参数是两个非常不同的东西。

您可以通过提供的scope:选项来覆盖键form_with

<%= form_with(model: [ :saasy, @signup ], scope: :saasy_signup_form, local: true) do |signup_form| %>

  <%= fields_for :account, @signup.account do |account_fields| %>
    Organization name: <%= account_fields.text_field :organization %>
  <% end %>

  <%= signup_form.submit %>
<% end %>

但是恕我直言,这只是愚蠢的。