Skip to content

Instantly share code, notes, and snippets.

@stephenbaidu
Created March 8, 2017 23:41
Show Gist options
  • Save stephenbaidu/7ea2171a00e0794d155cc5ccc950e10c to your computer and use it in GitHub Desktop.
Save stephenbaidu/7ea2171a00e0794d155cc5ccc950e10c to your computer and use it in GitHub Desktop.
Include Ruby/Rails module with arguments/options
# Usage
class Payment < ActiveRecord::Base
# Readonly columns
include Immutable.for :customer_id, :amount
end
# Implementation 1: Rails Concern
module Immutable
extend ActiveSupport::Concern
included do
validate :ensure_immutable
end
def self.for(*args)
mod = Immutable
mod.send(:define_method, :immutable_options) do
args
end
mod
end
private
def ensure_immutable
if persisted?
immutable_options.each do |attr|
errors[attr.to_sym] << 'immutable' if changed.include?(attr.to_s)
end
end
end
end
# Implementation 2: Ruby Module
module Immutable
def self.for(*args)
Module.new do
define_method :ensure_immutable do
if persisted?
args.each do |attr|
errors[attr.to_sym] << 'immutable' if changed.include?(attr.to_s)
end
end
end
def self.included(included_by)
included_by.validate :ensure_immutable
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment