Search code examples
ruby-on-railsrubydry

Rails keeping params DRY


I have a model named "seo"

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

Many models in my application has_one seo. For example

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

My question is, what is the best way to keep params in my controllers dry. For example I have the following code in my posts_controller

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

Every model will repeat the above. How do I keep this DRY?


Solution

  • I think this is an example where you could use a 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
    

    And for the controllers, you could add a method into AplicationController that allows simplified the call:

    # 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