Summarize the class extensions that you encounter in your work:
1, class Inheritance:
When more than one class is common to many methods, the common method part can be extracted, and the required class is related to inheritance.
Example:
Copy Code code as follows:
Class A < ActiveRecord::Base
def a
P "It was a"
End
End
Class B<a
End
Class C<a
End
B.NEW.A #=> "It was a"
C.NEW.A #=> "It was a"
2. Abstract class
When multiple classes want to inherit a class, the first method encounters a problem.
(Refer to an annotation of another person to describe the use of abstract classes https://ihower.tw/rails4/activerecord-others.html)
Single form of STI (Single-table inheritance)
It's a big question how to put an object into the inheritance concept, and the design of the relational library. Rails builds one of the simplest solutions, using only one data table to store the objects in the inheritance system, with a type of name that is named for this information.
To open the STI function, as the case may be, a field is called type, and the form string is available. Assuming that the following posts data table has a bit called type, then these three models will actually share posts a data table, and of course, these two are also inherited to the validates_presence_of:subject of the parent:-
Copy Code code as follows:
Class Post < ActiveRecord::Base
Validates_presence_of:subject
End
Class Guestpost < Post
End
Class Memberpost < Post
End
Let's go into the Rails console experiment and see that rails will automatically set the type of the fence according to the kind of work you use:
Copy Code code as follows:
Post = Guestpost.create (: Subject => "Guest")
Post.type # "Guestpost"
Post.id # 1
Post = Memberpost.create (: Subject => "Member")
Post.id # 2
Post.type # "Memberpost"
Guestpost.last # 1
Unfortunately, and because of this habit, you can't move the name of type to use it.
The biggest problem with STI is the amount of space spent, and the use of STI will be a waste of time if there are not many lines at the intersection of the system. If there is a larger number of unused bars, the pen will recommend not to use this function, so that individual types have their own data tables. To turn off STI, please parent add Self.abstract_class = True
Copy Code code as follows:
Class Post < ActiveRecord::Base
Self.abstract_class = True
End
Class Guestpost < Post
End
Class Memberpost < Post
End
Here the Guestpost and memberpost need to have their own migrations to build guest_posts and member_posts data sheets.
You can also introduce multiple dependencies in a class
Copy Code code as follows:
Class Dependency<post
Require_dependency ' Guestpost '
Require_dependency ' Memberpost '
End
3, class expansion mixed
Ruby's class is a single inheritance, the function of multiple inheritance needs to be implemented by Mixin (the mode of the model), that is, class expansion mixed. Example:
Copy Code code as follows:
Module Extract
def self.included (Base)
Base.extend (Classmethods)
End
Module Classmethods
def a
P "It was a"
End
End
End
Class A<activerecord::base
Include Extract
End
A.NEW.A #=> "It was a"
4, proxy class
When a function is more complex, of course, write Lib, as a function-oriented approach to deal with is very simple, you can use the proxy class to implement the object-oriented invocation.
Example:
Copy Code code as follows:
Class A<activerecord::base
def Generate_schedule
Generator = Generator::excelgenerator.new (self)
Generator.generate_schedule
End
End
Module generator
Class Excelgenerator
Attr_reader:excel,:workbook,:a,:worksheet
Attr_accessor:styles
Def initialize (a)
@excel | | = axlsx::P ackage.new
@workbook | | = @excel. Workbook
@worksheet = @workbook. Add_worksheet (: Name => ' Test generates an Excel file ')
@a | | = A
@styles | | = Hash.new
End
def Generate_schedule
#excel内容的具体定义
End
End
End
A.new.generate_schedule can implement a class instance method of a by proxy class Excelgenerator Generate_schedule
Of course, you can add a class instance method by include a model, and sometimes it can be mixed. The advantage of using a proxy class is that you can define a common part when multiple classes require the same method, and give an example of an email:
Copy Code code as follows:
Class A<activerecord::base
Include SendEmail
End
Class B<activerecord::base
Include SendEmail
End
Implementing the Introduction module:
Copy Code code as follows:
Module SendEmail
#include this module to CLASS::A and B
#use like that--a.first.send_email
def Send_email
Email.call_email (self)
End
End
Implementing a proxy class:
Copy Code code as follows:
Class Email < Actionmailer::base
Default:from => "Test@email.com"
def self.call_email (obj)
Define_method "#{obj.state}" do |obj|
@obj = obj
Mail (: to => @obj. Email: Subject => "xx title")
End
Send ("#{obj.state}"). Deliver
#根据不同对象obj. State gets different states, defines different methods, and send dispatches a template that invokes the state of the related object.
End
End
Ruby is flexible. There are, of course, many other ways to achieve more, and then slowly summarize.