Rails 3 Internals
-
Upload
andersonleite -
Category
Technology
-
view
1.748 -
download
1
description
Transcript of Rails 3 Internals
Rails 3 InternalsConhecendo detalhes do framework que fazem a diferença.
Anderson Leite
@anderson_leite
www.andersonleite.com.br
Tuesday, September 14, 2010
Rails 3 Internals
Rails 3
Architectural changes
Rails + Merb
Tuesday, September 14, 2010
Rails 3 Internals
Modularidade
Rails 3
Tuesday, September 14, 2010
Rails 3 Internals
ActiveRelation
ActiveModel
Railtie
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
Rails 3 Internals
Tuesday, September 14, 2010
Rails 3 Internals
Diego Carrion ??
Tuesday, September 14, 2010
Rails 3 Internals
Diego Carrion ??
Tuesday, September 14, 2010
Rails 3 Internals
Diego Carrion ??
Tuesday, September 14, 2010
Rails 3 Internals
Diego Carrion ??
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 2@models = Model.find(:all, :conditions => {:value => true} )
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)
# Rails 2@models = Model.find(:all, :conditions => {:value => true} )
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)
# Rails 2@models = Model.find(:all, :conditions => {:value => true} )
@models = @models.order(params[:order])
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)
# Rails 2@models = Model.find(:all, :conditions => {:value => true} )
@models = @models.order(params[:order])
@models = Model.where(:value => true).order(params[:order])
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)
# Rails 2@models = Model.find(:all, :conditions => {:value => true} )
@models = @models.order(params[:order])
@models = Model.where(:value => true).order(params[:order])
Array
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)
# Rails 2@models = Model.find(:all, :conditions => {:value => true} )
@models = @models.order(params[:order])
@models = Model.where(:value => true).order(params[:order])
Array
Relation
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)@models = @models.order(params[:order])
@models = Model.where(:value => true).order(params[:order])Relation
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)@models = @models.order(params[:order])
@models = Model.where(:value => true).order(params[:order])Relation
@models.each do |m|#...end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true)@models = @models.order(params[:order])
@models = Model.where(:value => true).order(params[:order])Relation
@models.each do |m|#...endLazy
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true).order(params[:order]).all
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true).order(params[:order]).all
Nova API (where, limit, having)
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true).order(params[:order]).allwhere
havingselectgrouporderlimitoffsetjoinsincludeslockreadonlyfrom
Nova API (where, limit, having)
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
# Rails 3@models = Model.where(:value => true).order(params[:order]).all
Relation
Encadeamento
wherehavingselectgrouporderlimitoffsetjoinsincludeslockreadonlyfrom
Nova API (where, limit, having)
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
1) internamente
2) minha app?
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
Nova API (where, limit, having)
Relation
Encadeamento
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
querys dinâmicas
class Post < ActiveRecord::Base belongs_to :usuario end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
querys dinâmicas
class Post < ActiveRecord::Base belongs_to :usuario endtexto
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
querys dinâmicas
class Post < ActiveRecord::Base belongs_to :usuario endtexto
> 1 ano
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
querys dinâmicas
class Post < ActiveRecord::Base belongs_to :usuario endtexto
> 1 anotrue
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
> rails 2{ :filter => { :conteudo => "texto", :comentarios => true, :usuario_id => "1" } }
conditionsnamed scopes
Tuesday, September 14, 2010
Rails 3 Internals
class PostTest < ActiveSupport::TestCase
setup do create_posts end
test "filtro em branco devolve todos os posts" do assert_equal Post.all, Post.filtered_relation({}).all end
def create_posts valid_attributes = { :body => "Hello.", :title => "Hi!", :content => "text", :user_id => 1, :published_at => Time.now }
@base = Post.create(valid_attributes) @quote = Post.create(valid_attributes.merge(:content => "quote")) @number2 = Post.create(valid_attributes.merge(:user_id => 2)) @old = Post.create(valid_attribtues.merge(:published_at => 1.year.ago))
end end
Tuesday, September 14, 2010
Rails 3 Internals
class PostTest < ActiveSupport::TestCase
setup do create_posts end
test "filtro em branco devolve todos os posts" do assert_equal Post.all, Post.filtered_relation({}).all end
def create_posts valid_attributes = { :body => "Hello.", :title => "Hi!", :content => "text", :user_id => 1, :published_at => Time.now }
@base = Post.create(valid_attributes) @quote = Post.create(valid_attributes.merge(:content => "quote")) @number2 = Post.create(valid_attributes.merge(:user_id => 2)) @old = Post.create(valid_attribtues.merge(:published_at => 1.year.ago))
end end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
end
def self.filtered_relation(params) relation = scoped
end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
end
def self.filtered_relation(params) relation = scoped
end
params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
end
def self.filtered_relation(params) relation = scoped
end
params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
end
def self.filter_by_content(value, relation) relation.where(:content => value) end
def self.filtered_relation(params) relation = scoped
end
params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
end
def self.filter_by_content(value, relation) relation.where(:content => value) end
test "apenas posts com conteudo especifico" do assert_equal @quote, Post.filtered_relation(:content => "quote").first end
def self.filtered_relation(params) relation = scoped
end
params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
end
def self.filter_by_content(value, relation) relation.where(:content => value) end
test "apenas posts com conteudo especifico" do assert_equal @quote, Post.filtered_relation(:content => "quote").first end
def self.filtered_relation(params) relation = scoped
end
params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
def self.filter_by_published_at(value, relation) value ? relation.where("published_at < ?", 1.month.ago) : relation end
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
def self.filter_by_published_at(value, relation) value ? relation.where("published_at < ?", 1.month.ago) : relation end
test "given a date filter, only gives us the filtered records" do assert_equal @old, Post.filtered_relation(:published_at => true).first end
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
def self.filter_by_published_at(value, relation) value ? relation.where("published_at < ?", 1.month.ago) : relation end
test "given a date filter, only gives us the filtered records" do assert_equal @old, Post.filtered_relation(:published_at => true).first end
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
def self.filter_by_comments(value, relation) if value relation.preload(:comments).\ select("posts.*, COUNT(comments.id) AS comment_count").\ from("posts, comments").having("comment_count > 0") else relation end end
test "given a comments count filter, only gives us the filtered records" do assert_equal @base, Post.filtered_relation(:comments => true).first end
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
def self.filter_by_comments(value, relation) if value relation.preload(:comments).\ select("posts.*, COUNT(comments.id) AS comment_count").\ from("posts, comments").having("comment_count > 0") else relation end end
test "given a comments count filter, only gives us the filtered records" do assert_equal @base, Post.filtered_relation(:comments => true).first end
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
def self.filter_by_comments(value, relation) if value relation.preload(:comments).\ select("posts.*, COUNT(comments.id) AS comment_count").\ from("posts, comments").having("comment_count > 0") else relation end end
test "given a comments count filter, only gives us the filtered records" do assert_equal @base, Post.filtered_relation(:comments => true).first end
class Post < ActiveRecord::Base belongs_to :user
def self.filtered_relation(params) relation = scoped params.each do |facet, value| relation = send("filter_by_#{facet}", value, relation) end
relation endend
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
test "given a content and comment filter, gives us filtered records" do @base.update_attribute(:content, "picture")
assert_equal @base, Post.filtered_relation(:content => "picture", :comments => true).first
end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
test "given a content and comment filter, gives us filtered records" do @base.update_attribute(:content, "picture")
assert_equal @base, Post.filtered_relation(:content => "picture", :comments => true).first
end
test "given a date and comment filter, gives us filtered records" do @base.update_attribute(:published_at, 2.years.ago)
assert_equal @base, Post.filtered_relation(:published_at => true, :comments => true).first
end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
test "given a content and comment filter, gives us filtered records" do @base.update_attribute(:content, "picture")
assert_equal @base, Post.filtered_relation(:content => "picture", :comments => true).first
end
test "given a date and comment filter, gives us filtered records" do @base.update_attribute(:published_at, 2.years.ago)
assert_equal @base, Post.filtered_relation(:published_at => true, :comments => true).first
end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
test "given a content and comment filter, gives us filtered records" do @base.update_attribute(:content, "picture")
assert_equal @base, Post.filtered_relation(:content => "picture", :comments => true).first
end
test "given a date and comment filter, gives us filtered records" do @base.update_attribute(:published_at, 2.years.ago)
assert_equal @base, Post.filtered_relation(:published_at => true, :comments => true).first
end
test "given a date and content filter, gives us filtered records" do @base.update_attribute(:published_at, 2.years.ago) @base.update_attribute(:content, "picture")
record = Post.filtered_relation(:published_at => true, :content => "picture").first
assert_equal @base, record end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
test "given a content and comment filter, gives us filtered records" do @base.update_attribute(:content, "picture")
assert_equal @base, Post.filtered_relation(:content => "picture", :comments => true).first
end
test "given a date and comment filter, gives us filtered records" do @base.update_attribute(:published_at, 2.years.ago)
assert_equal @base, Post.filtered_relation(:published_at => true, :comments => true).first
end
test "given a date and content filter, gives us filtered records" do @base.update_attribute(:published_at, 2.years.ago) @base.update_attribute(:content, "picture")
record = Post.filtered_relation(:published_at => true, :content => "picture").first
assert_equal @base, record end
Tuesday, September 14, 2010
ActiveRelation
Rails 3 Internals
posts = Post.filtered_relation(:comments => true).where(:user_id => 4).limit(3).order("id ASC")
posts.each do |post| # Do something here... end
Tuesday, September 14, 2010
Reflexão
Rails 3 Internals
Tuesday, September 14, 2010
Reflexão
Rails 3 Internals
Tuesday, September 14, 2010
class Message extend ActiveModel::Callbacks define_model_callbacks :deliver
def deliver _run_deliver_callbacks do puts "DELIVER!" end end
end
ActiveModel
Rails 3 Internals
Tuesday, September 14, 2010
class Message include ActiveModel::Validations
validates_presence_of :body, :user_id attr_accessor :body, :user_id, :posted_at
end m = Message.new(nil, 13) m.valid? # => false m.body = "Hello there!" m.valid? # => true
ActiveModel
Rails 3 Internals
Tuesday, September 14, 2010
class Message include ActiveModel::Validations
validates_presence_of :body, :user_id attr_accessor :body, :user_id, :posted_at
end m = Message.new(nil, 13) m.valid? # => false m.body = "Hello there!" m.valid? # => true
ActiveModel
Rails 3 Internals
AttributesCallbacksErrorsObservingSerializationTranslationValidations
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
class ProperCategoryValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) unless record.user.category_ids.include?(value) record.errors.add attribute, 'has bad category.' end end
end
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
class ProperCategoryValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) unless record.user.category_ids.include?(value) record.errors.add attribute, 'has bad category.' end end
end
validate :category_id, :proper_category => true
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
class ProperCategoryValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) unless record.user.category_ids.include?(value) record.errors.add attribute, 'has bad category.' end end
end
validate :category_id, :proper_category => true
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
class ProperCategoryValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) unless record.user.category_ids.include?(value) record.errors.add attribute, 'has bad category.' end end
end
validate :category_id, :proper_category => true
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
class ReallyComplexValidator < ActiveModel::Validator
def validate(record) record.errors[:base] << "Validacao A" unless valid_a (record) record.errors[:base] << "Validacao B" unless valid_b (record) record.errors[:base] << "Validacao C" unless valid_c (record) end
private
def valid_a (record) # ... end def valid_b (record) # ... end def valid_c (record) # ... end end
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
class ReallyComplexValidator < ActiveModel::Validator
def validate(record) record.errors[:base] << "Validacao A" unless valid_a (record) record.errors[:base] << "Validacao B" unless valid_b (record) record.errors[:base] << "Validacao C" unless valid_c (record) end
private
def valid_a (record) # ... end def valid_b (record) # ... end def valid_c (record) # ... end end
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
class ReallyComplexValidator < ActiveModel::Validator
def validate(record) record.errors[:base] << "Validacao A" unless valid_a (record) record.errors[:base] << "Validacao B" unless valid_b (record) record.errors[:base] << "Validacao C" unless valid_c (record) end
private
def valid_a (record) # ... end def valid_b (record) # ... end def valid_c (record) # ... end end
class NewsPost < ActiveRecord::Base validates_with ReallyComplexValidator end
Tuesday, September 14, 2010
ActiveModel
Rails 3 Internals
template rendering, controller logic, e database query results
<% cache do %> <% @posts.each do |post| %> <%= render :partial => 'post', :object => post %> <% end %>
<% end %>
Tuesday, September 14, 2010
ActiveRecord::Relationvs
ARel
Rails 3 Internals
Tuesday, September 14, 2010
Rails 3 Internals
Rails 3 > Modularidade
Desacoplamento
Tuesday, September 14, 2010
Rails 3 Internals
Opnionated ?
Meta-framework ?
Rails 3 > Modularidade
Tuesday, September 14, 2010
Rails 3 Internals
config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)run MinhaApp::Application
Rails 3
Tuesday, September 14, 2010
Railtie > Engine > Application
Rails 3 Internals
Inicializar Rails App
Coordenar processos de boot
Carregar plugins
Carregar ActiveSupport
Outros: database, logging, sessions
Tuesday, September 14, 2010
Rails 3 Internals
Tuesday, September 14, 2010
Railtie - autoload
Rails 3 Internals
Tuesday, September 14, 2010
Railtie - autoload
Rails 3 Internals
Tuesday, September 14, 2010
Railtie - autoload
Rails 3 Internals
Tuesday, September 14, 2010
Railtie
Rails 3 Internals
Tuesday, September 14, 2010
Railtie
Rails 3 Internals
Tuesday, September 14, 2010
Railtie
Rails 3 Internals
Tuesday, September 14, 2010
Railtie
Rails 3 Internals
Tuesday, September 14, 2010
Railtie
Rails 3 Internals
Tuesday, September 14, 2010
Railtie
Rails 3 Internals
Frameworks Rails > Rails Plugins
Tuesday, September 14, 2010
Rails 3 Internals
Railtie ... Plugins....ARel....
Tuesday, September 14, 2010
Railtie ... Plugins....ARel....
Rails 3 Internals
require 'filtered_relation'require 'rails'
module FilteredRelation class Railtie < Rails::Railtie railtie_name :filtered_relation
endend
Tuesday, September 14, 2010
Railtie ... Plugins....ARel....
Rails 3 Internals
require 'filtered_relation'require 'rails'
module FilteredRelation class Railtie < Rails::Railtie railtie_name :filtered_relation
endend
código
Tuesday, September 14, 2010
Links
Rails 3 Internals
http://www.engineyard.com/blog/2010/rails-and-merb-merge-orm-agnosticism-part-5-of-6/
http://vimeo.com/14550567
http://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb
http://piotrsarnacki.com/2010/06/18/rails-internals-railties/
http://rubyonrails.org/screencasts/rails3/action-controller
http://www.igvita.com/2010/08/04/rails-3-internals-railtie-creating-plugins/
http://piotrsarnacki.com/2010/06/18/rails-internals-railties/
http://metautonomo.us/2010/05/11/activerecord-relation-vs-arel/
Tuesday, September 14, 2010
Rails 3 InternalsConhecendo detalhes do framework que fazem a diferença.
Anderson Leite
@anderson_leite
www.andersonleite.com.br
Obrigado!
Tuesday, September 14, 2010