Rails 保持参数干燥

Rails keeping params DRY

我有一个名为 "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

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

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

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

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

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

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

并且在 post 控制器中,您可以像这样干地使用它们

class PostController < ResourceController    
            def resource_name
                :post
            end
end

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

class BlogController < ResourceController    
                def resource_name
                    :blog
                end
    end

我认为这是您可以使用 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