presentation technico-commercial-ruby-on-rails
TRANSCRIPT
Présentationtechnico-commerciale
de Ruby on RailsYann Klis, juin 2013
RubyonRails
RubyonRails
interprété> 1 + 1=> 2
gestion de la mémoire
Garbage Collector
orienté objet pur> 1 + 1=> 2> 1.send(:+, 1)=> 2
orienté objet pur> nil.nil ?=> true
orienté objet pur> true.class=> TrueClass
dynamique> ary = []=> []> ary.class.class_eval { attr_accessor :total_entries}=> nil> ary.total_entries = 42=> 42> ary.total_entries=> 42
class Printing def method_missing(m, *args) if (name = /^test_(.+)$/.match(m.id2name)) print name[1] end endEnd
> printing = Printing.new> printing.test_hello=> "hello"> printing.test_pipo=> "pipo"
dynamique
blocklambda, fonction anonyme, etc.
> ["a","b","c"].each_with_index{|element,i| puts i}012
blocklambda, fonction anonyme, etc.
> ["a", "b", "c"].map{|element| element.upcase}=> ["A", "B", "C"]
lisibilité> 5.times { print "Odelay!" }
> Exit unless "restaurant".include?("aura")
> ['toast', 'cheese', 'wine'].each{|food| print food.capitalize}
Ruby ? Quel Ruby ?1.8.71.9.32.0.0
Ruby ? Quel Ruby ?1.8.7 MRI1.9.3 MRI2.0.0 MRIrbx 2.0.0
JRuby 1.7.4
rbenvrvm
# rbenv list 1.8.7-p358 1.9.3-p392 2.0.0-p0* 2.0.0-p195 (set by /home/yannski/.rbenv/version)
rbenv# rbenv install jruby-1.7.4 # rbenv local jruby-1.7.4
bundler & Gemfilesource 'https://rubygems.org'
gem 'rails', '4.0.0'gem 'rails-i18n'gem 'sass-rails', '~> 4.0.0'gem 'haml-rails', '>= 4.0.0'gem 'mongoid', github: 'mongoid/mongoid'
RubyonRails
ModelViewController
ModelViewController
Conventionover
Configuration
Conventionover
Configuration
environments# ls -l config/environments/development.rbproduction.rbtest.rb
DRY
DRYDon't Repeat Yourself
ActiveRecordM in MVC
class Product < ActiveRecord::Baseend
ActiveRecord / migrations
class CreateProducts < ActiveRecord::Migration def change create_table :products do |t| t.string :name t.text :description
t.timestamps end endend
db/migrate/20130626120509_create_products.rb
app/models/product.rb
ActiveRecord / migrations
mysql> show tables;+---------------------------------+| Tables_in_monapppli_development |+---------------------------------+| products || schema_migrations |+---------------------------------+2 rows in set (0.00 sec)
mysql> describe schema_migrations;+---------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+---------+--------------+------+-----+---------+-------+| version | varchar(255) | NO | PRI | NULL | |+---------+--------------+------+-----+---------+-------+1 row in set (0.00 sec)
mysql> select * from schema_migrations;+----------------+| version |+----------------+| 20130626120509 |+----------------+1 row in set (0.00 sec)
irb(main):001:0> product = Product.new=> #<Product id: nil, name: nil, description: nil, created_at: nil, updated_at: nil>
irb(main):002:0> product.name = "Macbook"=> "Macbook"
irb(main):003:0> product.save (0.4ms) BEGIN SQL (0.3ms) INSERT INTO `products` (`created_at`, `name`, `updated_at`) VALUES ('2013-06-26 12:08:17', 'Macbook', '2013-06-26 12:08:17') (4.7ms) COMMIT=> true
ActiveRecord / migrations
irb(main):004:0> Product.count (0.5ms) SELECT COUNT(*) FROM `products`=> 1
irb(main):005:0> Product.first Product Load (0.5ms) SELECT `products`.* FROM `products` ORDER BY `products`.`id` ASC LIMIT 1=> #<Product id: 1, name: "Macbook", description: nil, created_at: "2013-06-26 12:08:17", updated_at: "2013-06-26 12:08:17">
irb(main):006:0> Product.where(name: "Macbook") Product Load (0.8ms) SELECT `products`.* FROM `products` WHERE `products`.`name` = 'Macbook'=> #<ActiveRecord::Relation [#<Product id: 1, name: "Macbook", description: nil, created_at: "2013-06-26 12:08:17", updated_at: "2013-06-26 12:08:17">]>
irb(main):008:0> Product.where(name: "Macbook").first Product Load (0.7ms) SELECT `products`.* FROM `products` WHERE `products`.`name` = 'Macbook' ORDER BY `products`.`id` ASC LIMIT 1=> #<Product id: 1, name: "Macbook", description: nil, created_at: "2013-06-26 12:08:17", updated_at: "2013-06-26 12:08:17">
ActiveRecord / query
> Product.where(name: "Macbook") Product Load (0.8ms) SELECT `products`.* FROM `products` WHERE `products`.`name` = 'Macbook'=> #<ActiveRecord::Relation [#<Product id: 1, name: "Macbook", description: nil, created_at: "2013-06-26 12:08:17", updated_at: "2013-06-26 12:08:17">]>
> Product.where(name: "Macbook").to_a Product Load (0.4ms) SELECT `products`.* FROM `products` WHERE `products`.`name` = 'Macbook'=> [#<Product id: 1, name: "Macbook", description: nil, created_at: "2013-06-26 12:08:17", updated_at: "2013-06-26 12:08:17">]
ActiveRecord / query
class Product validates_presence_of :nameend
ActiveRecord / validations
class CreateProducts < ActiveRecord::Migration def change create_table :products do |t| t.string :name t.text :description
t.timestamps end endend
db/migrate/20130626120509_create_products.rb
app/models/product.rb
> product = Product.new=> #<Product id: nil, name: nil, description: nil, created_at: nil, updated_at: nil>
> product.save (0.3ms) BEGIN (0.2ms) ROLLBACK=> false
> product.errors=> #<ActiveModel::Errors:0x007f2f9fb1bec8 @base=#<Product id: nil, name: nil, description: nil, created_at: nil, updated_at: nil>, @messages={:name=>["can't be blank"]}>
ActiveRecord / validations
class Product validates_presence_of :name belongs_to :categoryend
ActiveRecord / associations
app/models/product.rb
class Category has_many :productsend
app/models/category.rb
class Product
before_validate :reformat
before_save :check_name
after_save :rebuild_category
after_destroy :destroy_category_if_empty
end
ActiveRecord / life cycle
app/models/product.rb
ActiveModelActiveModel::Model
ActiveModel::CallbacksActiveModel::Validations
ActiveModel::DirtyActiveModel::AttributeMethods
ActiveModel::SerializationActiveModel::Translation
Routing
Restful
asset pipeline
//= require jquery//= require jquery_ujs//= require jquery-ui//= require bootstrap//= require bootstrap-datepicker//= require jquery_nested_form//= require ckeditor/init//= require_tree .
app/assets/javascripts/application.js
asset pipeline
*= require "custombootstrap"*= require "fontawesome"*= require "datepicker"*= require_self
app/assets/stylesheets/application.css.scss
asset pipeline
ActiveSupport
> "Je suis à la gare".blank ?=> false
ActiveSupport
> "".present?=> false
ActiveSupport
> "Je suis à la gare".parameterize=> "je-suis-a-la-gare"
ActiveSupport
> "John était allongé à la table d'un café quand soudain le loup apparu.".truncate(22)=> "John était allongé …"
ActiveSupport
ActionView
products.html.erbproducts.html.hamlmovies.json.erbmovies.xml.builder
ActionView
TestTests unitaires des models, des controllers, des helpersTests fonctionnels (rspec, capybara, etc.)
rails console
> Product.where(name: "Macbook") Product Load (0.8ms) SELECT `products`.* FROM `products` WHERE `products`.`name` = 'Macbook'=> #<ActiveRecord::Relation [#<Product id: 1, name: "Macbook", description: nil, created_at: "2013-06-26 12:08:17", updated_at: "2013-06-26 12:08:17">]>
> Product.where(name: "Macbook").to_a Product Load (0.4ms) SELECT `products`.* FROM `products` WHERE `products`.`name` = 'Macbook'=> [#<Product id: 1, name: "Macbook", description: nil, created_at: "2013-06-26 12:08:17", updated_at: "2013-06-26 12:08:17">]
ActiveRecord / query
rails server
rails generate
debugger
i18n
Communauté RubyUne certaine mentalité, certes...
rakemake en ruby
capistranodéploiement
rubygems.orgrepository centralisé des gems
deviseauthentification
omniauthomniauth-facebook, omniauth-twitter,
omniauth-dailymotion, omniauth-github, ...
paperclipupload de fichiers, stockage, thumbnails, etc.
will_paginatepagination
state_machinemachine à états...
airbrakegestion des exceptions
resquegestion des jobs asynchrones
(backend Redis)
Apprendre Railshttp://railsforzombies.org/http://guides.rubyonrails.org/Formation (chez Novelys!)