class MailyHerald::Context
Abstraction layer for accessing collections of Entities and their attributes. Information provided by scope is used while sending {MailyHerald::Mailing mailings}.
{Context} defines following:
-
Entity scope -
ActiveRecord::Relation
, list of Entities that will be returned by {Context}. -
Entity model name - deducted automatically from scope.
-
Entity attributes - Defined as procs that can be evaluated for every item of the scope (single Entity).
-
Entity email - defined as proc or string/symbol (email method name).
Attributes
Identification name of the {Context}.
This can be then used in {MailyHerald.context} method to fetch the {Context}.
@see MailyHerald.context
Friendly name of the {Context}.
Displayed ie. in the Web UI.
Public Class Methods
Creates {Context} and sets its name.
# File lib/maily_herald/context.rb, line 99 def initialize name @name = name end
Public Instance Methods
Sepcify or return {Context} attributes.
Defines Entity attributes that can be accessed using this Context
. Attributes
defined this way are then accesible in Liquid templates in Generic Mailer ({MailyHerald::Mailer#generic}).
If block passed, it is used to create Context
Attributes
.
If no block given, current attributes are returned.
# File lib/maily_herald/context.rb, line 202 def attributes &block if block_given? @attributes = Attributes.new block else @attributes end end
Obtains {Context} attributes in a form of (nested) Hash
which values are procs each returning single Entity attribute value.
# File lib/maily_herald/context.rb, line 212 def attributes_list return {} unless @attributes attributes = @attributes.dup attributes.setup attributes.for_drop end
Entity email address.
Can be eitner Proc
or attribute name (string, symbol).
If block passed, it is saved as destination proc. Block has to:
-
accept single Entity object,
-
return Entity email.
If no block given, destination
attribute is returned (a string, symbol or proc).
# File lib/maily_herald/context.rb, line 132 def destination &block if block_given? @destination = block else @destination end end
Returns Entity email attribute name only if it is not defined as a proc.
# File lib/maily_herald/context.rb, line 141 def destination_attribute @destination unless @destination.respond_to?(:call) end
Fetches Entity’s email address based on {Context} destination definition.
# File lib/maily_herald/context.rb, line 146 def destination_for entity destination_attribute ? entity.send(@destination) : @destination.call(entity) end
Returns Liquid drop created from Context
attributes.
# File lib/maily_herald/context.rb, line 221 def drop_for entity, subscription return {} unless @attributes attributes = @attributes.dup attributes.setup entity, subscription Drop.new(attributes.for_drop) end
Fetches the Entity model class based on scope.
# File lib/maily_herald/context.rb, line 118 def model @model ||= @scope.call.klass end
Defines or returns Entity scope - collection of Entities.
If block passed, it is saved as scope proc. Block has to return ActiveRecord::Relation
containing entity objects that will belong to scope.
If no block given, scope proc is called and entity collection returned.
# File lib/maily_herald/context.rb, line 109 def scope &block if block_given? @scope = block else @scope.call end end
Simply filter Entity scope by email.
If destination is provided in form of Entity attribute name (not the proc), this method creates the scope filtered by ‘query` email using SQL LIKE.
@param query [String] email address which is being searched. @return [ActiveRecord::Relation] collection filtered by email address
# File lib/maily_herald/context.rb, line 157 def scope_like query if destination_attribute scope.where("#{model.table_name}.#{destination_attribute} LIKE (?)", "%#{query}%") end end
Returns Entity collection scope with joined {MailyHerald::Subscription}.
@param list [List, Fixnum, String] {MailyHerald::List} reference @param mode [:inner, :outer] SQL JOIN mode
# File lib/maily_herald/context.rb, line 167 def scope_with_subscription list, mode = :inner list_id = case list when List list.id when Fixnum list when String list.to_i else raise ArgumentError end join_mode = case mode when :outer "LEFT OUTER JOIN" else "INNER JOIN" end subscription_fields_select = Subscription.columns.collect{|c| "#{Subscription.table_name}.#{c.name} AS maily_subscription_#{c.name}"}.join(", ") scope.select("#{model.table_name}.*, #{subscription_fields_select}").joins( "#{join_mode} #{Subscription.table_name} ON #{Subscription.table_name}.entity_id = #{model.table_name}.id AND #{Subscription.table_name}.entity_type = '#{model.base_class.to_s}' AND #{Subscription.table_name}.list_id = '#{list_id}'" ) end