鉴于Rails 4.1,两个控制器CRM::CompaniesController
和CRM::ContactPeople
,两个模型CRM::Company
和CRM::ContactPerson
以及以下路径:
namespace :crm do
resources :companies do
resources :contact_people
end
end
生成的URL帮助程序只包含一次CRM命名空间,这正是我想要的:
crm_company_contact_people GET /crm/companies/:company_id/contact_people(.:format)
new_crm_company_contact_person GET /crm/companies/:company_id/contact_people/new(.:format)
# ...
但是,对URL帮助程序使用Array方法
= form_for([@crm_company, @crm_contact_person]) do |f|
尝试生成每个资源命名空间的URL:
undefined method `crm_company_crm_contact_people_path' for #<#<Class...
我想要&#34; crm&#34;在我的路径中只在开头一次(除非它打破了常见的Rails方法)并且明确地将URL添加到每个表单将是很难看的。有什么我可以做的(可能在路由,模型或第一个form_for参数),以便Rails知道如何构建正确的路径?或者是否有更多类似Rails的方法来生成这种结构,以便Rails自动知道如何构建路径?
答案 0 :(得分:1)
您需要在调用form_for
:
= form_for([:crm, @crm_company, @crm_contact_person]) do |f|
此外,由于您正在使用命名空间模型,因此需要在它们上定义以下类方法(from rails/rails issue #10705)以忽略命名空间:
def self.use_relative_model_naming?
true
end
答案 1 :(得分:0)
我尝试了几种方法来为我找到最烦人的方法。我首先要改变CRM命名空间以使用相对模型命名:
module CRM
def self.use_relative_model_naming?
true
end
end
但是,这会从每个对象(包括公司)中删除命名空间。所以以下内容不再适用:
= url_for @crm_company
# undefined method `company_path'
为避免这种情况,我尝试通过修改模型名称来仅对特定模型进行命名空间(请注意,这比URL生成有更多副作用):
class CRM::ContactPerson < ActiveRecord::Base
def self.model_name
ActiveModel::Name.new(self, CRM)
end
end
现在,以下网址可以正常使用:
= url_for @crm_company
= url_for [@crm_company, @crm_contact_person]
但是如果CRM :: ContactPerson是浅层嵌套并且作为CRM的子项出现并直接作为CRM的孩子,那么上面的问题会重新出现:
= url_for @crm_contact_person
# undefined method `contact_person_path'
在这种情况下,我们可以将嵌套和未嵌套的部分拆分为CRM :: Companies :: ContactPerson和CRM :: ContactPerson,并使用CRM :: Companies模块的相对模型命名。但是,这似乎是很多开销,甚至可能比使用显式URL帮助程序更糟糕。
所以现在我找不到一个全面的解决方案,但至少只有嵌套资源的解决方案才能正常工作。