From 890b9dd4439986e306ec4fc0067a00effa606204 Mon Sep 17 00:00:00 2001 From: Weston Platter 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. + + +# MyApp/app/decorators/models/blorgh/post_decorator.rb + +Blorgh::Post.class_eval do + def time_since_created + Time.current - created_at + end +end + + +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). + + +# 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 + + 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: - s.add_development_dependency "moo" -- cgit v1.2.3 From 738a0e17eb2f7b6656e8a4a9fa58d4609bcc7eaa Mon Sep 17 00:00:00 2001 From: Francesco Rodriguez 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: + s.add_development_dependency "moo" -- cgit v1.2.3