diff --git a/guides/source/engines.textile b/guides/source/engines.textile index 11c837be32..de4bbb5656 100644 --- a/guides/source/engines.textile +++ b/guides/source/engines.textile @@ -655,15 +655,17 @@ This tells the application that you still want to perform a +GET+ request to the h3. Improving engine functionality -This section looks at overriding or adding functionality to the views, controllers and models provided by an engine. +This section explains how to add and/or override engine MVC functionality in the main Rails application. -h4. Overriding Models +h4. Overriding Models and Controllers -Engine Models can be extended by (1) implementing decorators, or (2) including modules. +Engine model and controller classes can be extended by open classing them in the main Rails application (since model and controller classes are just Ruby classes that inherit Rails specific functionality). Open classing an Engine class redefines it for use in the main applicaiton. This is usually implemented by using the decorator pattern. -h5. Decorators +For simple class modifications use Class#class_eval, and for complex class modifications, consider using ActiveSupport::Concern. -Decorators extends Engine's model classes in the main application by open classing Engine models at run time execution. +h5. Implementing Decorator Pattern Using Class#class_eval + +**Adding** Post#time_since_created, # MyApp/app/decorators/models/blorgh/post_decorator.rb @@ -675,15 +677,48 @@ Blorgh::Post.class_eval do end -h5. Modules + +# Blorgh/app/models/post.rb -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. +class Post < ActiveRecord::Base + :has_many :comments +end + -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). + +**Overriding** Post#summary + + +# MyApp/app/decorators/models/blorgh/post_decorator.rb + +Blorgh::Post.class_eval do + def summary + "#{title} - #{truncate(text)}" + end +end + + + +# Blorgh/app/models/post.rb + +class Post < ActiveRecord::Base + :has_many :comments + def summary + "#{title}" + end +end + + + +h5. Implementing Decorator Pattern Using ActiveSupport::Concern + +Using Class#class_eval is great for simple adjustments, but for more complex class modifications, you might want to consider using ActiveSupport::Concern. ["**ActiveSupport::Concern**":http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html] helps manage load order of interlinked dependencies at run time allowing you to significantly modularize your code. + +**Adding** Post#time_since_created
+**Overriding** Post#summary # MyApp/app/models/blorgh/post.rb -# overrides Blorgh's original Post model class Blorgh::Post < ActiveRecord::Base include Blorgh::Concerns::Models::Post @@ -691,24 +726,30 @@ class Blorgh::Post < ActiveRecord::Base def time_since_created Time.current - created_at end + + def summary + "#{title} - #{truncate(text)}" + 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/lib/concerns/models/post -# Blorgh/app/concerns/models/post - -module Blorg::Concerns::Models::Post +module Blorgh::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' causes the included code to be evaluated in the + # conext where it is included (post.rb), rather than be + # executed in the module's context (blorgh/concerns/models/post). included do attr_accessor :author_name belongs_to :author, :class_name => "User" @@ -722,9 +763,8 @@ module Blorg::Concerns::Models::Post end end - # methods defined here will be instance methods by default - def some_method - 'some method string' + def summary + "#{title}" end module ClassMethods