Module: DataMapper::Is::Remixable::RemixerClassMethods
- Includes:
- Assertions
- Defined in:
- lib/dm-is-remixable/is/remixable.rb
Overview
Class Method Summary collapse
Instance Method Summary collapse
-
#enhance(remixable, remixable_model = nil, &block) ⇒ Object
-
enhance ==== Description Enhance a remix; allows nesting remixables, adding columns & functions to a remixed resource ==== Parameters remixable <Symbol> Name of remixable to enhance (plural or singular name of is :remixable module) model_class <Class, symbol, String> Name of the remixable generated Model Class.
-
- #is_remixable? ⇒ Boolean
-
#remix(cardinality, remixable, options = {}) ⇒ Object
-
remix ==== Description Remixes a Remixable Module ==== Parameters cardinality <~Fixnum> 1, n, x …
-
-
#remixables ⇒ Object
-
remixables ==== Description Returns a hash of the remixables used by this class ==== Returns <Hash> Remixable Class Name => Remixed Class Name.
-
Class Method Details
.included(base) ⇒ Object
73 |
# File 'lib/dm-is-remixable/is/remixable.rb', line 73 def self.included(base);end |
Instance Method Details
#enhance(remixable, remixable_model = nil, &block) ⇒ Object
-
enhance
Description
Enhance a remix; allows nesting remixables, adding columns & functions to a remixed resource
Parameters
remixable <Symbol> Name of remixable to enhance (plural or singular name of is :remixable module)
model_class <Class, symbol, String> Name of the remixable generated Model Class.
block <Proc> Enhancements to perform
Examples
When you have one remixable:
class Video
include DataMapper::Resource
remix Comment
enhance :comments do
remix n, :votes #This would result in something like YouTubes Voting comments up/down
property :updated_at, DateTime
def backwards; self.test.reverse; end;
end
When you remixe the same remixable modules twice:
class Article
include DataMapper::Resource
remix n, :taggings, :for => User, :model => "UserArticleTagging"
remix n, :taggings, :for => Bot, :model => "BotArticleTagging"
enhance :taggings, "UserArticleTagging" do
property :updated_at, DateTime
belongs_to :user
belongs_to :tag
end
enhance :taggings, "BotArticleTagging" do
belongs_to :bot
belongs_to :tag
end
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/dm-is-remixable/is/remixable.rb', line 260 def enhance(remixable,remixable_model=nil, &block) inflector = DataMapper::Inflector # always use innermost singular underscored constant name remixable_name = inflector.singularize(remixable.to_s) remixable_name = inflector.underscore(remixable_name).to_sym class_name = if remixable_model.nil? @remixables[remixable_name].keys.first else name = inflector.demodulize(remixable_model.to_s) inflector.underscore(name).to_sym end model = @remixables[remixable_name][class_name][:model] unless @remixables[remixable_name][class_name].nil? unless model.nil? model.class_eval &block else raise Exception, "#{remixable} must be remixed with :model option as #{remixable_model} before it can be enhanced" end end |
#is_remixable? ⇒ Boolean
75 76 77 |
# File 'lib/dm-is-remixable/is/remixable.rb', line 75 def is_remixable? @is_remixable ||= false end |
#remix(cardinality, remixable, options = {}) ⇒ Object
-
remix
Description
Remixes a Remixable Module
Parameters
cardinality <~Fixnum> 1, n, x ...
remixable <Symbol> plural of remixable; i.e. Comment => :comments
options <Hash> options hash
:model <String> Remixed Model name (Also creates a storage_name as tableize(:model))
This is the class that will be created from the Remixable Module
The storage_name can be changed via 'enhance' in the class that is remixing
Default: self.name.downcase + "_" + remixable.suffix.pluralize
:as <String> Alters the name that the remixable items will be available through, this WILL NOT
create the standard accessor
Default: tableize(:class_name)
:for|:on <String> Class name to join to through Remixable
This will create a M:M relationship THROUGH the remixable, rather than
a 1:M with the remixable
:via <String> changes the name of the second id in a unary relationship
see example below; only used when remixing a module between the same class twice
ie: self.class.to_s == options[:for||:on]
:unique <Boolean> Only works with :for|:on; creates a unique composite key
over the two table id's
Examples
Given: User (Class), Addressable (Module)
One-To-Many; Class-To-Remixable
remix n, :addressables, :model => "UserAddress", :as => "addresses"
Tables: users, user_addresses
Classes: User, UserAddress
User.user_addresses << UserAddress.new => Raise No Method Exception since it was alias with :as
User.addresses << UserAddress.new
--------------------------------------------
--------------------------------------------
Given: User (Class), Video (Class), Commentable (Module)
Many-To-Many; Class-To-Class through RemixableIntermediate (Video allows Commentable for User)
Video.remix n, :commentables
:for => 'User' #:for & :on have same effect, just a choice of wording...
--------------------------------------------
--------------------------------------------
Given: User (Class), User (Class), Commentable (Module)
Many-To-Many Unary relationship between User & User through comments
User.remix n, :commentables, :as => "comments", :for => 'User', :via => "commentor"
=> This would create user_id and commentor_id as the
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/dm-is-remixable/is/remixable.rb', line 139 def remix(cardinality, remixable, ={}) assert_kind_of 'remixable', Symbol, String, Module #A map for remixable names to Remixed Models @remixables = {} if @remixables.nil? # Allow nested modules to be remixable to better support using dm-is-remixable in gems # Example (from my upcoming dm-is-rateable gem) # remix n, "DataMapper::Is::Rateable::Rating", :as => :ratings remixable_module = case remixable when Symbol then DataMapper::Ext::Object.full_const_get(Object, DataMapper::Inflector.classify(remixable)) when String then DataMapper::Ext::Object.full_const_get(Object, remixable) when Module then remixable end unless remixable_module.is_remixable? raise Exception, "#{remixable_module} is not remixable" end if [:class_name] warn '+options[:class_name]+ is deprecated, use :model instead' [:model] = .delete(:class_name) end inflector = DataMapper::Inflector model = inflector.underscore(self.name) model = inflector.camelize(model + '_' + remixable_module.suffix) #Merge defaults/options = { :as => nil, :model => model, :for => nil, :on => nil, :unique => false, :via => nil, :connect => false }.update() #Make sure the class hasn't been remixed already unless DataMapper::Ext::Object.full_const_defined?(inflector.classify([:model])) #Storage name of our remixed model [:table_name] = DataMapper::Inflector.tableize(inflector.demodulize([:model])) #Other model to mix with in case of M:M through Remixable [:other_model] = [:for] || [:on] DataMapper.logger.info "Generating Remixed Model: #{[:model]}" model = generate_remixed_model(remixable_module, ) # map the remixable to the remixed model # since this will be used from 'enhance api' i think it makes perfect sense to # always refer to a remixable by its demodulized underscored constant name remixable_key = inflector.demodulize(remixable_module.name) remixable_key = inflector.underscore(remixable_key).to_sym populate_remixables_mapping(model, .merge(:remixable_key => remixable_key)) # attach RemixerClassMethods and RemixerInstanceMethods to remixer if defined by remixee if DataMapper::Ext::Object.full_const_defined? "#{remixable_module}::RemixerClassMethods" extend DataMapper::Ext::Object.full_const_get("#{remixable_module}::RemixerClassMethods") end if DataMapper::Ext::Object.full_const_defined? "#{remixable_module}::RemixerInstanceMethods" include DataMapper::Ext::Object.full_const_get("#{remixable_module}::RemixerInstanceMethods") end #Create relationships between Remixer and remixed class if [:other_model] # M:M Class-To-Class w/ Remixable Module as intermediate table # has n and belongs_to (or One-To-Many) remix_many_to_many cardinality, model, else # 1:M Class-To-Remixable # has n and belongs_to (or One-To-Many) remix_one_to_many cardinality, model, end else DataMapper.logger.warn "#{__FILE__}:#{__LINE__} warning: already remixed constant #{[:model]}" end end |
#remixables ⇒ Object
-
remixables
Description
Returns a hash of the remixables used by this class
Returns
<Hash> Remixable Class Name => Remixed Class Name
84 85 86 |
# File 'lib/dm-is-remixable/is/remixable.rb', line 84 def remixables @remixables end |