From 890b9dd4439986e306ec4fc0067a00effa606204 Mon Sep 17 00:00:00 2001
From: Weston Platter <westonplatter@gmail.com>
Date: Sun, 22 Jul 2012 17:24:49 -0400
Subject: added 2 strategies for extending engine models

---
 guides/source/engines.textile | 79 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 78 insertions(+), 1 deletion(-)

(limited to 'guides/source/engines.textile')

diff --git a/guides/source/engines.textile b/guides/source/engines.textile
index 53c2845731..db23c1c584 100644
--- a/guides/source/engines.textile
+++ b/guides/source/engines.textile
@@ -657,6 +657,84 @@ h3. Improving engine functionality
 
 This section looks at overriding or adding functionality to the views, controllers and models provided by an engine.
 
+h4. Overriding Models
+
+Engine Models can be extended by (1) implementing decorators, or (2) including modules.
+
+h5. Decorators
+
+Decorators extends Engine's model classes in the main application by open classing Engine models at run time execution.
+
+<ruby>
+# MyApp/app/decorators/models/blorgh/post_decorator.rb
+
+Blorgh::Post.class_eval do
+  def time_since_created
+    Time.current - created_at
+  end
+end
+</ruby>
+
+h5. Modules
+
+The other strategy is to create modules within the Engine holding all the models' code and include these in the respective Engine's model classes. Thus the Engine's model classes contain a mere include line referencing the respective module.
+
+Engine models can be overriden in the main application by creating a file with the Engine's same namespace and including the module originally referenced in the Engine's model class. ["**ActiveSupport::Concern**":http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html] helps manage the correct ordering of module dependencies at run time (it's worth it to reach the linked documentation).
+
+<ruby>
+# MyApp/app/models/blorgh/post.rb
+# overrides Blorgh's original Post model
+
+class Blorgh::Post < ActiveRecord::Base
+  include Blorgh::Concerns::Models::Post
+
+  def time_since_created
+    Time.current - created_at
+  end
+end
+
+
+# Blorgh/app/models/post.rb
+# this class is overriden by the MyApp Post model
+
+class Post < ActiveRecord::Base
+  include Blorgh::Concerns::Models::Post
+end
+
+
+# Blorgh/app/concerns/models/post
+
+module Blorg::Concerns::Models::Post
+  extend ActiveSupport::Concern
+  
+  # 'included do' causes the code within to be evaluated in the conext
+  #   where it is included, rather be executed in the module's context.
+  included do
+    attr_accessor :author_name
+    belongs_to :author, :class_name => "User"
+     
+    before_save :set_author
+     
+    private
+    
+    def set_author
+      self.author = User.find_or_create_by_name(author_name)
+    end
+  end
+
+  # methods defined here will be instance methods by default
+  def some_method
+    'some method string'
+  end
+
+  module ClassMethods
+    def some_class_method
+      'some class method string'
+    end
+  end
+end
+</ruby>
+
 h4. Overriding views
 
 When Rails looks for a view to render, it will first look in the +app/views+ directory of the application. If it cannot find the view there, then it will check in the +app/views+ directories of all engines which have this directory.
@@ -772,7 +850,6 @@ s.add_dependency "moo"
 To specify a dependency that should only be installed as a development
 dependency of the application, specify it like this:
 
-<ruby>
 s.add_development_dependency "moo"
 </ruby>
 
-- 
cgit v1.2.3


From 738a0e17eb2f7b6656e8a4a9fa58d4609bcc7eaa Mon Sep 17 00:00:00 2001
From: Francesco Rodriguez <lrodriguezsanc@gmail.com>
Date: Sun, 22 Jul 2012 19:51:17 -0500
Subject: fix removed ruby tag in commit 890b9dd [ci skip]

---
 guides/source/engines.textile | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'guides/source/engines.textile')

diff --git a/guides/source/engines.textile b/guides/source/engines.textile
index db23c1c584..11c837be32 100644
--- a/guides/source/engines.textile
+++ b/guides/source/engines.textile
@@ -706,17 +706,17 @@ end
 
 module Blorg::Concerns::Models::Post
   extend ActiveSupport::Concern
-  
+
   # 'included do' causes the code within to be evaluated in the conext
   #   where it is included, rather be executed in the module's context.
   included do
     attr_accessor :author_name
     belongs_to :author, :class_name => "User"
-     
+
     before_save :set_author
-     
+
     private
-    
+
     def set_author
       self.author = User.find_or_create_by_name(author_name)
     end
@@ -850,6 +850,7 @@ s.add_dependency "moo"
 To specify a dependency that should only be installed as a development
 dependency of the application, specify it like this:
 
+<ruby>
 s.add_development_dependency "moo"
 </ruby>
 
-- 
cgit v1.2.3

