The Concern provides a mechanism for composing modules.Concerns are pieces of code that allow you to better organize the code that you write. This feature has actually been around for a long time prior to Rails 4, Rails 4 merely creates the folders for you and sets up the environment.
Included
==================================================
Module defines the callback included which is called when a module is included into another class or module. For example see the following code:
==================================================
module Named
def self.included(base)
base.validates_presence_of :first_name, :last_name
end
def full_name
"#{first_name} #{last_name}"
end
end
..........................
class Person
include Named
end
When Person includes Named, the included method is called on Named with a reference to Person. Now, what if you want a module that builds upon Named?
=================================================
module Mailable
include Named
def self.included(base)
email_regexp = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
base.validates_format_of :email, with: email_regexp
end
def send_greeting
mail = WelcomeMailer.greet(email, first_name, last_name)
mail.deliver
end
end
.................................................................................................................................
if we do
require 'mailable'
then it will gives
# => NoMethodError: undefined method `validates_presence_of' for Mailable:Module
This will fail when Named is included into Mailable. The Name.included callback will be executed with Mailable as the base, but Mailable doesn't define validates_presence_of:
==================================================
We really want these modules to wait until they are included in your model before the included callback is invoked. Concern works around this issue for us:
module Named
extend ActiveSupport::Concern
included do
base.validates_presence_of :first_name, :last_name
end
end
module Mailable
extend ActiveSupport::Concern
include Named
included do
email_regexp = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
base.validates_format_of :email, with: email_regexp
end
end
First a module extends Concern, and then instead of defining def self.included it calls included with a block. Concern delays calling these blocks until your module is included in something that is not a Concern.
Included
==================================================
Module defines the callback included which is called when a module is included into another class or module. For example see the following code:
==================================================
module Named
def self.included(base)
base.validates_presence_of :first_name, :last_name
end
def full_name
"#{first_name} #{last_name}"
end
end
..........................
class Person
include Named
end
When Person includes Named, the included method is called on Named with a reference to Person. Now, what if you want a module that builds upon Named?
=================================================
module Mailable
include Named
def self.included(base)
email_regexp = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
base.validates_format_of :email, with: email_regexp
end
def send_greeting
mail = WelcomeMailer.greet(email, first_name, last_name)
mail.deliver
end
end
.................................................................................................................................
if we do
require 'mailable'
then it will gives
# => NoMethodError: undefined method `validates_presence_of' for Mailable:Module
This will fail when Named is included into Mailable. The Name.included callback will be executed with Mailable as the base, but Mailable doesn't define validates_presence_of:
==================================================
We really want these modules to wait until they are included in your model before the included callback is invoked. Concern works around this issue for us:
module Named
extend ActiveSupport::Concern
included do
base.validates_presence_of :first_name, :last_name
end
end
module Mailable
extend ActiveSupport::Concern
include Named
included do
email_regexp = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
base.validates_format_of :email, with: email_regexp
end
end
First a module extends Concern, and then instead of defining def self.included it calls included with a block. Concern delays calling these blocks until your module is included in something that is not a Concern.
No comments:
Post a Comment