mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
edit of previous content
explains how to add/override engine classes in the main rails app via 1) Class#class_eval 2) ActiveSupport::Concern
This commit is contained in:
parent
957e3d4966
commit
39674d1e90
1 changed files with 59 additions and 19 deletions
|
@ -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,
|
||||
|
||||
<ruby>
|
||||
# MyApp/app/decorators/models/blorgh/post_decorator.rb
|
||||
|
@ -675,15 +677,48 @@ Blorgh::Post.class_eval do
|
|||
end
|
||||
</ruby>
|
||||
|
||||
h5. Modules
|
||||
<ruby>
|
||||
# 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
|
||||
</ruby>
|
||||
|
||||
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
|
||||
|
||||
<ruby>
|
||||
# MyApp/app/decorators/models/blorgh/post_decorator.rb
|
||||
|
||||
Blorgh::Post.class_eval do
|
||||
def summary
|
||||
"#{title} - #{truncate(text)}"
|
||||
end
|
||||
end
|
||||
</ruby>
|
||||
|
||||
<ruby>
|
||||
# Blorgh/app/models/post.rb
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
:has_many :comments
|
||||
def summary
|
||||
"#{title}"
|
||||
end
|
||||
end
|
||||
</ruby>
|
||||
|
||||
|
||||
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<br/>
|
||||
**Overriding** Post#summary
|
||||
|
||||
<ruby>
|
||||
# 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
|
||||
</ruby>
|
||||
|
||||
|
||||
<ruby>
|
||||
# Blorgh/app/models/post.rb
|
||||
# this class is overriden by the MyApp Post model
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
include Blorgh::Concerns::Models::Post
|
||||
end
|
||||
</ruby>
|
||||
|
||||
<ruby>
|
||||
# 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
|
||||
|
|
Loading…
Reference in a new issue