【问题标题】:Rails form_for with namespaced model names带有命名空间模型名称的 Rails form_for
【发布时间】:2017-12-03 21:01:18
【问题描述】:

我有一个嵌套资源 projects/tasks/new 和一个 form_for,但我不知道如何自动生成所需的 URL:

module Projects
  class Project < ApplicationRecord
    has_many :tasks
  end
end

module Projects
  class Task < ApplicationRecord
    belongs_to :project
  end
end

# in view files
<%= form_for [@project, @task] do |f| %> # => produces URL of projects_project_tasks_path

我希望 URL 是 project_tasks_path,但 form_for 使用命名空间 Projects::Project 作为 URL 前缀。

我目前的解决方案是使用单独的 new.html.erbedit.html.erb 查看文件来手动指定 URL:

# new.html.erb
<%= form_for @task, url: project_tasks_path(@project) do |f| %>
  <%= render "form", f: f %>
<% end %>

# edit.html.erb
<%= form_for @task, url: project_task_path(@project, @task) do |f| %>
  <%= render "form", f: f %>
<% end %>

这可行,但复制了不必要的代码。请注意,我将嵌套资源用于新建和编辑操作,因为我必须在任务资源上拥有项目上下文。

如何让form_for 生成所需的 URL 并拥有一个 form.html.erb 文件而不是 2 个?

【问题讨论】:

    标签: ruby-on-rails forms namespaces


    【解决方案1】:

    您可以通过覆盖模型名称来做到这一点:

    class Projects::Project < ApplicationRecord
      def model_name
        ActiveModel::Name.new(self, nil, "Project")
      end
    end
    
    class Projects::Task < ApplicationRecord
      def model_name
        ActiveModel::Name.new(self, nil, "Task")
      end
    end
    

    这会将用于生成 url 的属性 Projects::Project.model_name.param_keyprojects_project 更改为 project

    见:

    【讨论】:

    • 这行得通,但我想知道是否有比更新每个模型更清洁的方法?我知道我可以做一些快速的元编程并创建一个覆盖它的关注点/模块......我只是假设有一种传统的方法可以做到这一点。谢谢!
    • 你可以在超类中而不是在每个类中进行。
    猜你喜欢
    • 1970-01-01
    • 2018-09-23
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 2012-09-10
    • 2013-01-14
    相关资源
    最近更新 更多