$30 off During Our Annual Pro Sale. View Details »

Learning Ruby's Dynamism with Rails

wtnabe
November 23, 2013

Learning Ruby's Dynamism with Rails

* Class-exp with AR
* include and extend with AS::Concern
* Standard Callbacks

wtnabe

November 23, 2013
Tweet

More Decks by wtnabe

Other Decks in Programming

Transcript

  1. Learning Ruby's Dynamism
    with Rails
    @wtnabe
    Kanazawa.rb meetup #15
    2013-11-23 (Sat) at IT Plaza Musashi

    View Slide

  2. Topics

    View Slide

  3. Class-exp with AR
    include and extend with AS::Concern
    Standard Callbacks

    View Slide

  4. Class-exp with
    ActiveRecord

    View Slide

  5. ActiveRecord example
    class Book < ActiveRecord::Base
    belongs_to :bookstand
    validates :name, :presence => true
    scope :done, -> {where(:done => true)}
    def recent?
    published_at >= 1.year.ago
    end
    end

    View Slide

  6. ActiveRecord Pattern
    Class has table and ER definition
    Instance has DB record and relative
    methods

    View Slide

  7. Just another OOPL
    class Book extends ActiveRecord\Model {
    static $belongs_to = array(
    array('bookstand')
    );
    static $validates_presence_of = array(
    array('name')
    );
    public static function done() {}
    public function is_recent() {}
    }

    View Slide

  8. class Book < ActiveRecord::Base
    belongs_to :bookstand
    validates :name, :presence => true
    scope :done, -> {where(:done => true)}
    def recent?
    published_at >= 1.year.ago
    end
    end

    View Slide

  9. class Book < ActiveRecord::Base
    # class method call
    belongs_to :bookstand
    # class method call
    validates :name, :presence => true
    # class method call
    scope :done, -> {where(:done => true)}
    # instance method definition
    def recent?
    published_at >= 1.year.ago
    end
    end

    View Slide

  10. Ruby's Class
    Class is expression
    class keyword changes context
    It runs all
    class methods callable in class context

    View Slide

  11. include and extend with
    ActiveSupport::Concern

    View Slide

  12. new Rails 4 app.
    app
    ├── assets
    │ ├── images
    │ ├── javascripts
    │ └── stylesheets
    ├── controllers
    │ └── concerns <-- what ?
    ├── helpers
    ├── mailers
    ├── models
    │ └── concerns <-- what ?
    └── views
    └── layouts

    View Slide

  13. ActiveSupport::Concern
    Actually added from ActiveSupport 3.0

    View Slide

  14. What does it do ?
    include & extend

    View Slide

  15. include
    module ModA
    def methodA; p 'methodA'; end
    end
    class KlassA
    include ModA
    end
    KlassA.new.methodA # => "methodA"

    View Slide

  16. extend
    module ModB
    def methodB; p 'methodB'; end
    end
    class KlassB
    extend ModB
    end
    KlassB.methodB # => "methodB"

    View Slide

  17. Concern
    module M
    extend ActiveSupport::Concern
    included do
    scope :foo, :conditions => {:created_at => nil}
    end
    module ClassMethods
    def cm; puts 'I am a class method'; end
    end
    module InstanceMethods
    def im; puts 'I am an instance method'; end
    end
    end

    View Slide

  18. When to use
    class ModelA < ActiveRecord::Base
    include M
    end
    class ModelB < ActiveRecord::Base
    include M
    end
    treat common attributes with multi-models

    View Slide

  19. ActiveRecord
    call class methods
    define class methods
    define instance methods

    View Slide

  20. class Book < ActiveRecord::Base
    # call class methods
    belongs_to :bookstand
    validates :name, :presence => true
    scope :done, -> {where(:done => true)}
    # define class methods
    class << self
    def recent
    self.where(:published_ad >= 1.year.ago)
    end
    end
    # define instance methods
    def recent?
    published_at >= 1.year.ago
    end
    end

    View Slide

  21. ActiveSupport::Concern
    module M
    included do
    # call class methods
    end
    module ClassMethods
    ...
    end
    module InstanceMethods
    ...
    end
    end

    View Slide

  22. AS::Concern is
    a AR's best friend
    cf. https://www.ruby-lang.org/

    View Slide

  23. Standard Callbacks

    View Slide

  24. Rails Callback Examples
    before_validation
    after_save
    before_action ( before_filter )
    called Filter, but Callback internally

    View Slide

  25. How to use
    class Controller < ApplicationController
    before_action :auth,
    :unless => :logged_in?
    end
    class Model < ActiveRecord::Base
    before_validation do
    normalize_attributes
    end
    end
    ※ :unless keyword is allowed from ActiveSupport::Callbacks 4.0

    View Slide

  26. Ruby has many Callbacks

    View Slide

  27. Module.private_methods.sort.grep(/ed\z/)
    # =>
    [:inherited, :included, :extended,
    :prepended, :method_added,
    :method_removed, :method_undefined,
    :protected, :singleton_method_added,
    :singleton_method_removed,
    :singleton_method_undefined]

    View Slide

  28. Object#initialize, Object#method_messing,
    Module#append_features, ...
    append_features is called before execute include

    View Slide

  29. ex1) extended
    module M
    extend ActiveSupport::Concern
    end
    module ActiveSupport
    module Concern
    def self.extended(base)
    ...
    end
    end
    end

    View Slide

  30. ex2) inherited
    class Klass
    def self.inherited(name)
    raise StandardError,
    "#{name} cannot inherit #{self}"
    end
    end

    View Slide

  31. Similar to Final keyword
    class Subklass < Klass; end
    # => ...:3:in `inherited':
    # Subklass cannot inherit Klass (StandardE

    View Slide

  32. Conclusion

    View Slide

  33. Ruby is Dynamic !
    Class is expression
    Class can be modified easily with
    AS::Concern
    Useful Standard Callbacks

    View Slide

  34. Rails uses Ruby's dynamism
    very well

    View Slide

  35. Enjoy Rails & Ruby !

    View Slide