我遇到了范围问题。 我已经定义了
# routes.rb
resources :asientos, module:'asientos'
# app/models/asientos/asiento.rb
module Asientos
class Asiento < ActiveRecord:Base
end
end
# app/controllers/asientos/asientos_controller.rb
module Asientos
class AsientosController < ApplicationController
def new
@asiento = Asientos::Asiento.new
end
end
end
# app/views/asientos/asientos/new
<%= form_for(@asiento) do |f| %>
...
asientos GET /asientos(.:format) asientos/asientos#index
POST /asientos(.:format) asientos/asientos#create
new_asiento GET /asientos/new(.:format) asientos/asientos#new
edit_asiento GET /asientos/:id/edit(.:format) asientos/asientos#edit
asiento GET /asientos/:id(.:format) asientos/asientos#show
PATCH /asientos/:id(.:format) asientos/asientos#update
PUT /asientos/:id(.:format) asientos/asientos#update
DELETE /asientos/:id(.:format) asientos/asientos#destroy
现在每当表单尝试渲染时,我都会
undefined method `asientos_asiento_index_path' for #<#<Class:0x000000065b3b40>:0x00000006ba5f30>
我见过一些像
这样的答案Module route in Rails with form_for(@object)
但是他们都没有提出明确的解决方案,或者建议进行某种修补。
此外,form_for现在生成asientos_前缀,并且在我的控制器中现在我还要将params.require(:asientos)重命名为params.require(:asientos_asientos)...不漂亮......
任何建议(除了撤消命名空间)都会非常感激。提前谢谢。
修改
似乎通过在模块定义中添加以下内容,路由按预期生成,没有“范围”
module Asientos
def self.use_relative_model_naming?
true
end
...
end
但它仍然想要一个asientos_index_path ......“未定义的方法`asientos_index_path'”
答案 0 :(得分:1)
好吧,在深入了解大量文章后,我找到了答案,并且有些帖子指出它与Inflections有关。 我的应用程序具有西班牙语的自定义变形,其中的变形看起来像:
Usuario -> Usuarios
Asiento -> Asientos
ItemAsiento -> ItemsAsiento
你会注意到它会使第一个单词复数化。话虽如此,从 rails / activemodel / lib / active_model / naming.rb 中提取的rails源代码中的以下代码显示了发生的内容
def initialize(klass, namespace = nil, name = nil)
@name = name || klass.name
raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank?
@unnamespaced = @name.sub(/^#{namespace.name}::/, "") if namespace
@klass = klass
@singular = _singularize(@name)
@plural = ActiveSupport::Inflector.pluralize(@singular)
@element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(@name))
@human = ActiveSupport::Inflector.humanize(@element)
@collection = ActiveSupport::Inflector.tableize(@name)
@param_key = (namespace ? _singularize(@unnamespaced) : @singular)
@i18n_key = @name.underscore.to_sym
@route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural.dup)
@singular_route_key = ActiveSupport::Inflector.singularize(@route_key)
@route_key << "_index" if @plural == @singular
end
由于我的类在Asientos名称空间下,@ name变为Asientos :: Asiento,@ ununspaced =“Asiento”,@ xsular =“asientos_asiento”,@ popral =“asientos_asiento”,这里提出了问题。如果复数和单数都相等,则@route_key会后缀。
但为什么这些是平等的?由于西班牙语的变形使第一个单词多元化,并且它不知道名称空间,因此“asientos_asiento”被认为是复数(从变形的立场来看是真的,但由于第一部分是命名空间而不是模型名称,所以错误)。
我想这里的约定对我有用,因为对话似乎假设最后一部分始终是模型名称,因此英语复数将始终正常工作。 这不应该发生,因为rails已经检测到命名空间,它不应该依赖于@name本身,而是剥离命名空间,然后在没有命名空间的情况下单一化和复数化。
猴子补丁......我们走了......
感谢大家。
答案 1 :(得分:0)
您需要在form_for帮助器中指定模块/命名空间,如下所示:
<% form_for [:asientos, @asiento] do |f| %>