【问题标题】:Rails keeping params DRYRails 保持参数 DRY
【发布时间】:2019-09-20 06:36:25
【问题描述】:

我有一个名为“seo”的模型

class Seo < ApplicationRecord
    belongs_to :seoable, polymorphic: true
    # more code
  end

我的应用程序中的许多模型 has_one seo。例如

 class Post < ApplicationRecord
    has_one :seo, as: :seoable
    accepts_nested_attributes_for :seo, dependent: :destroy
    # more code
  end

我的问题是,让控制器中的参数保持干燥的最佳方法是什么。例如,我的 posts_controller 中有以下代码

def post_params
  params.require(:post).permit(seo_attributes: [:id, :title, :meta_description, :etc])
end

每个模型都会重复上述内容。如何保持干燥?

【问题讨论】:

    标签: ruby-on-rails ruby dry


    【解决方案1】:

    我认为这是一个可以使用 concern 的示例:

    # in app/models/concern/seoable.rb
    require 'active_support/concern'
    
    module Seoable
      extend ActiveSupport::Concern
      included do
        has_one :seo, as: :seoable
        accepts_nested_attributes_for :seo, dependent: :destroy
      end
    end
    
    # in your models
    class Post < ApplicationRecord
      include Seoable
    end
    

    对于控制器,您可以在AplicationController 中添加一个方法来简化调用:

    # in the application_controller
    def params_with_seo_attributes(namespace)
      params.require(namespace).permit(seo_attributes: [:id, :title, :meta_description, :etc])
    end
    
    # and use it in your controllers like this
    def post_params
      params_with_seo_attributes(:post)
    end
    

    【讨论】:

    • 显然 permit 可以使用一次。我稍微修改了你的代码。 def params_with_seo_attributes [seo_attributes: [:id, :title, :meta_description, :etc]] 在我的后期控制器中结束 def post_params allowed_pa​​rams = [:foo, :bar] + params_with_seo_attributes params.require(:post).permit(permitted_pa​​rams) end
    【解决方案2】:

    您可以创建一个具有 post_params 方法的控制器,然后需要使用它的其余控制器可以从该控制器继承

    【讨论】:

      【解决方案3】:

      你可以有一个像下面这样的基本控制器

      class ResourceController < ApplicationController
              private
              def resource_params
                  params.require(resource_name).permit(seo_attributes: [:id, :title, :meta_description, :etc])
              end
      end
      

      在后期控制器中,您可以像这样使用它们

      class PostController < ResourceController    
                  def resource_name
                      :post
                  end
      end
      

      并再次在任何其他控制器中使用,如博客,如下所示

      class BlogController < ResourceController    
                      def resource_name
                          :blog
                      end
          end
      

      【讨论】:

        【解决方案4】:

        因此,如果 has_one :seo, as: :seoableaccepts_nested_attributes_for :seo, dependent: :destroy 在多个模型中重复出现,那么您可以使用 Rails Concerns

        如果您想了解如何提出疑虑,请参阅this question

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-08
          • 2014-09-06
          • 1970-01-01
          • 1970-01-01
          • 2011-07-04
          • 1970-01-01
          相关资源
          最近更新 更多