Skip to content

Instantly share code, notes, and snippets.

@aaronjensen
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronjensen/efa824496470b74f0fd7 to your computer and use it in GitHub Desktop.
Save aaronjensen/efa824496470b74f0fd7 to your computer and use it in GitHub Desktop.
active_interaction default instance eval procs
require 'spec_helper'
describe Interaction do
TestInteraction = Class.new(Interaction) do
model :user
string :first_name
model_fields user: [:first_name]
end
describe ".model_fields" do
it "can get defaults from a model" do
user = mock_model User, first_name: "Bob"
interaction = TestInteraction.new(user: user)
expect(interaction.first_name).to eq "Bob"
end
it "can expose model fields" do
user = mock_model User, first_name: "Bob"
interaction = TestInteraction.new(user: user)
expect(interaction.model_fields(:user)).to eq(first_name: "Bob")
end
it "does not get polluted by other interactions" do
TestInteraction2 = Class.new(Interaction) do
model :user
string :last_name
model_fields user: [:last_name]
end
user = mock_model User, first_name: "Bob"
interaction = TestInteraction.new(user: user)
expect(interaction.model_fields(:user)).to eq(first_name: "Bob")
end
it "respects imported filters" do
ImportInteraction = Class.new(Interaction) do
import_filters TestInteraction
model :user
string :last_name
model_fields user: [:last_name]
end
user = mock_model User, first_name: "Bob", last_name: "Jenkins"
interaction = ImportInteraction.new(user: user)
expect(interaction.model_fields(:user)).to eq(first_name: "Bob", last_name: "Jenkins")
end
end
describe "proc defaults" do
DefaultInteraction = Class.new(Interaction) do
string :foo
string :bar, default: -> { foo }
end
it "can use procs as defaults" do
interaction = DefaultInteraction.new(foo: "test")
expect(interaction.bar).to eq "test"
end
it "respect imported filters" do
SubInteraction = Class.new(Interaction) do
import_filters DefaultInteraction
end
interaction = SubInteraction.new(foo: "test")
expect(interaction.bar).to eq "test"
end
end
end
class Interaction < ActiveInteraction::Base
def initialize(*args)
super
initialize_defaults
end
def self.model_fields(options)
options.each do |model, fields|
_model_fields[model] += fields
fields.each do |field|
default_for field, -> { send(model).send(field) }
end
end
end
def self.model_fields_for(model)
_model_fields.fetch(model)
end
def self._model_fields
@_model_fields ||= Hash.new { |h, k| h[k] = Set.new }
end
def self.import_filters(klass, options = {})
super
return unless klass.respond_to? :_model_fields
model_fields(klass._model_fields)
klass._defaults.each do |field, default|
default_for field, default
end
end
def self.initialize_filter(filter)
if filter.options[:default].is_a? Proc
default = filter.options.delete(:default)
default_for filter.name, default
end
super(filter)
end
def self.default_for(name, default)
_defaults[name] = default
end
def self._defaults
@_defaults ||= Hash.new
end
def initialize_defaults
self.class._defaults.each do |field, default|
next unless send(field).nil?
send(:"#{field}=", instance_exec(&default))
end
end
def model_fields(model)
self.class.model_fields_for(model).map do |field|
[field, send(field)]
end.to_h
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment