Rails中的模块路由with form_for(@object)

时间:2016-05-31 22:19:29

标签: ruby-on-rails controller routes namespaces simple-form-for

我已将Controller Entities :: Customers

命名为
class Entities::CustomersController < ApplicationController
...
end

和命名空间的ActiveRecord模型:

class Entities::Customer < Entities::User

end

在我的routes.rb文件中我有:

 resources :customers, module: :entities

模块:实体在那里,因为我不想拥有如下的路线:

/ entities / customers 但仅限:

/客户

问题在我渲染表单时开始:

<%= simple_form_for(@customer) do |f| %>
      <%= f.input :email %>
      <%= f.input :password %>
      <%= f.input :name %>
      <%= f.button :submit %>
<% end %>

这会引发错误:类的未定义方法`entities_customer_path'

所以错误是rails认为正确的路径是前缀实体。

Rake路线给我:

             Prefix Verb   URI Pattern                   Controller#Action
      customers GET    /customers(.:format)          entities/customers#index
                POST   /customers(.:format)          entities/customers#create
   new_customer GET    /customers/new(.:format)      entities/customers#new
  edit_customer GET    /customers/:id/edit(.:format) entities/customers#edit
       customer GET    /customers/:id(.:format)      entities/customers#show
                PATCH  /customers/:id(.:format)      entities/customers#update
                PUT    /customers/:id(.:format)      entities/customers#update
                DELETE /customers/:id(.:format)      entities/customers#destroy

2 个答案:

答案 0 :(得分:1)

好的,经过一番努力,我找到了解决这个问题的方法:

simple_form_for(@model)生成前缀为实体的路由,因为它不知道路由中有作用域路径。

所以在我的_form部分中,我必须手动告诉我使用哪条路线取决于我的部分中的action_name辅助方法。

<%
case action_name
  when 'new', 'create'
   action = send("customers_path")
   method = :post
  when 'edit', 'update'
   action = send("customer_path", @customer)
   method = :put
end
%>

<%= simple_form_for(@customer, url: action, method: method) do |f| %>
      <%= f.input :email %>
      <%= f.input :password %>
      <%= f.input :name %>
      <%= f.button :submit %>
<% end %>

答案 1 :(得分:0)

所有项目的全局解决方案可以覆盖ApplicationHelper方法form_with(当前在Rails 5中):

aplication_helper.rb

  def form_with(**options)
    if options[:model]
      class_name = options[:model].class.name.demodulize.underscore
      create_route_name = class_name.pluralize

      options[:scope] = class_name
      options[:url] = if options[:model].new_record?
                        send("#{create_route_name}_path")
                        # form action = "customers_path"
                      else
                        send("#{class_name}_path", options[:model])
                        # form action = "customer/45"
                      end

      # post for create and patch for update:
      options[:method] = :patch if options[:model].persisted?

      options[:model] = nil

      super
    end
  end

因此,如果有类似的路线

 scope module: 'site' do
  resources :translations
 end

您可以在_form.html.erb中进行编码:

<%= form_with(model: @translation, method: :patch) do |form| %>

没有错误