Rails 4.0Nikola Šantić
• MVC Web Framework • Verzija 1.0 - prosinac 2005.• “Convention over configuration”, DRY• Najbolji je• 235.000 siteova
Ruby on Rails
• MVC Web Framework • Verzija 1.0 - prosinac 2005.• “Convention over configuration”, DRY• Najbolji je• 235.000 siteova
Ruby on Rails
• MVC Web Framework • Verzija 1.0 - prosinac 2005.• “Convention over configuration”, DRY• Najbolji je• 235.000 siteova
Ruby on Rails
• MVC Web Framework • Verzija 1.0 - prosinac 2005.• “Convention over configuration”, DRY• Najbolji je• 235.000 siteova
Ruby on Rails
• MVC Web Framework • Verzija 1.0 - prosinac 2005.• “Convention over configuration”, DRY• Najbolji je• 235.000 siteova
Ruby on Rails
Promjene
Promjene
verzije commits files changed lines changed
1.2 - 2.0 1,989 1,106 61,774 +38,554 -
2.3 - 3.0 10,000+ 2,334 131,438 +106,109 -
3.0 - 3.1 6,818 1,522 74,115 +62,646 -
3.2 - 4.0? 7,304 2,005 94,231 +92,069 -
Pretpremijera
# Gemfile
# gem 'rails', '3.2.8'gem 'rails', github: 'rails/rails'
$ bundle update
NOVE STVARI
Strong Parameters
# app/models/user.rbclass User < ActiveRecord::Base end
# app/controllers/users_controller.rbclass UsersController < ApplicationController def update # params = {user: {name: 'Nikola', age: 25}} @user = User.find(params[:id]) @user = @user.update_attributes(params[:user]) redirect_to @user endend
Mass assignment
# app/models/user.rbclass User < ActiveRecord::Base end
# app/controllers/users_controller.rbclass UsersController < ApplicationController def update # params = {user: {name: 'Nikola', admin: true}} @user = User.find(params[:id]) @user = @user.update_attributes(params[:user]) redirect_to @user endend
Mass assignment
# app/models/user.rbclass User < ActiveRecord::Base end
# app/controllers/users_controller.rbclass UsersController < ApplicationController def update # params = {user: {name: 'Nikola', admin: true}} @user = User.find(params[:id]) @user = @user.update_attributes(params[:user]) redirect_to @user endend
# @user.admin?# => true
Mass assignment
# app/models/user.rbclass User < ActiveRecord::Base attr_accessible :name end
# app/controllers/users_controller.rbclass UsersController < ApplicationController def update # params = {user: {name: 'Nikola', admin: true}} @user = User.find(params[:id]) @user = @user.update_attributes(params[:user]) redirect_to @user endend
# @user.admin?# => false
Mass assignment
config.active_record.whitelist_attributes = false
# app/models/user.rbclass User < ActiveRecord::Baseend
# app/controllers/users_controller.rbclass UsersController < ApplicationController def update # params = {user: {name: 'Nikola', admin: true}} @user = User.find(params[:id]) @user = @user.update_attributes(user_params) redirect_to @user end
private def user_params params.require(:user).permit(:name) end end
Strong parameters
params.require(:user).permit(:name, :email, :password)
Strong parameters
params.require(:user).permit(:name, :email, :password)
Strong parameters
POST /usersparams = {username: ‘Budala’}
params.require(:user).permit(:name, :email, :password)
Strong parameters
POST /usersparams = {username: ‘Budala’}
<= 400 Bad Request
params.require(:user).permit(:name, :email, :password)
Strong parameters
POST /usersparams = {user: {name: ‘Nikola’, admin: true}}
params.require(:user).permit(:name, :email, :password)
Strong parameters
POST /usersparams = {user: {name: ‘Nikola’, admin: true}}
<= 201 CREATED
User.find_by_name(‘Nikola’).admin?=> false
# app/controllers/users_controller.rbclass UsersController < ApplicationController def user_params params.require(:user).permit(:name) end end
# app/controllers/admin/users_controller.rbclass Admin::UsersController < ApplicationController def user_params params.require(:user).permit(User.attribute_names) end end
Višestruke uloge
https://github.com/rails/strong_parameters
Dostupan već danas!
ActiveSupport::Queue
• delayed_job• Resque• Sidekiq• ...
Background job - Prije
class ExpensiveOperation def run # ... endend
Rails.queue.push(ExpensiveOperation.new)
Background job - Sada
config.queue = :asynchronousconfig.queue = :synchronous
config.queue = :resque
Podešavanje
config.action_mailer.async = true
Asinkroni ActionMailer
ActionController::Live
class MyController < ActionController::Base def index 100.times { response.stream.write "hello world\n" } response.stream.close endend
Streaming
class MyController < ActionController::Base include ActionController::Live def index 100.times { response.stream.write "hello world\n" } response.stream.close endend
Streaming
class MyController < ActionController::Base include ActionController::Live def index 100.times { response.stream.write "hello world\n" } response.stream.close endend
Streaming
WEBrick
class MyController < ActionController::Base include ActionController::Live def index 100.times { response.stream.write "hello world\n" } response.stream.close endend
Streaming
WEBrick
class MyController < ActionController::Base include ActionController::Live def index 100.times { response.stream.write "hello world\n" } response.stream.close endend
Streaming
WEBrick Unicorn
class MyController < ActionController::Base include ActionController::Live def index 100.times { response.stream.write "hello world\n" } response.stream.close endend
Streaming
WEBrick Unicorn
class MyController < ActionController::Base include ActionController::Live def index 100.times { response.stream.write "hello world\n" } response.stream.close endend
Streaming
WEBrick UnicornRainbows
PumaThin
Rails 4.0 > Node.js ?
STARE STVARI
Cache Digest
@user
Babuška caching
@project
@project
@task
@task
@task
<%# app/views/users/show.html.erb %><% cache [ 'v1', @user ] do %> <h1> <%= @user.name %> </h1> <%= render @user.projects %><% end %>
<%# app/views/projects/_project.html.erb %><% cache [ 'v1', project ] do %> <%= project.description %> <%= render project.tasks %><% end %>
<%# app/views/tasks/_task.html.erb %><% cache [ 'v1', task ] do %> Todo: <%= task.content %><% end %>
Babuška caching
<%# app/views/users/show.html.erb %><% cache [ 'v1', @user ] do %> <h1> <%= @user.name %> </h1> <p> Vaši projekti: </p> <%= render @user.projects %><% end %>
<%# app/views/projects/_project.html.erb %><% cache [ 'v1', project ] do %> <%= project.description %> <%= render project.tasks %><% end %>
<%# app/views/tasks/_task.html.erb %><% cache [ 'v1', task ] do %> Todo: <%= task.content %><% end %>
Babuška caching
<%# app/views/users/show.html.erb %><% cache [ 'v2', @user ] do %> <h1> <%= @user.name %> </h1> <p> Vaši projekti: </p> <%= render @user.projects %><% end %>
<%# app/views/projects/_project.html.erb %><% cache [ 'v1', project ] do %> <%= project.description %> <%= render project.tasks %><% end %>
<%# app/views/tasks/_task.html.erb %><% cache [ 'v1', task ] do %> Todo: <%= task.content %><% end %>
Babuška caching
<%# app/views/users/show.html.erb %><% cache [ 'v2', @user ] do %> <h1> <%= @user.name %> </h1> <p> Vaši projekti: </p> <%= render @user.projects %><% end %>
<%# app/views/projects/_project.html.erb %><% cache [ 'v1', project ] do %> <%= project.description %> <%= render project.tasks %><% end %>
<%# app/views/tasks/_task.html.erb %><% cache [ 'v1', task ] do %> Todo: <%= task.content %> Date: <%= task.date %><% end %>
Babuška caching
<%# app/views/users/show.html.erb %><% cache [ 'v3', @user ] do %> <h1> <%= @user.name %> </h1> <p> Vaši projekti: </p> <%= render @user.projects %><% end %>
<%# app/views/projects/_project.html.erb %><% cache [ 'v2', project ] do %> <%= project.description %> <%= render project.tasks %><% end %>
<%# app/views/tasks/_task.html.erb %><% cache [ 'v2', task ] do %> Todo: <%= task.content %> Date: <%= task.date %><% end %>
Babuška caching
<%# app/views/users/show.html.erb %><% cache @user do %> <h1> <%= @user.name %> </h1> <%= render @user.projects %><% end %>
<%# app/views/projects/_project.html.erb %><% cache project do %> <%= project.description %> <%= render project.tasks %><% end %>
<%# app/views/tasks/_task.html.erb %><% cache task do %> Todo: <%= task.content %><% end %>
Sada
Čarolijom! (+ koristi MD5 templatea i partiala
kao cache key)
Kako???
https://github.com/rails/cache_digests
Dostupan već danas!
Routing concerns
BCX::Application.routes.draw do resources :messages { resources :comments } resources :forwards { resources :comments } resources :uploads { resources :comments }end
Prije
BCX::Application.routes.draw do concern :commentable do resources :comments end
resources :messages, :forwards, :uploads, concerns: :commentableend
Sada
https://github.com/rails/routing_concerns
Dostupan već danas!
ActiveRecord::Relation
User.firstUser.last
Prvi koji?
User.firstUser.last
Prvi koji?
Sortirani po id-u
SELECT "users".* FROM "users" ORDER BY id LIMIT 1
Koji svi?
User.allVraća ActiveRecord::Relation objekt
Koji svi?
User.allVraća ActiveRecord::Relation objekt
@users = User.all@users = @users.where(name: params[:name]) if params[:name]@users = @users.order(params[:sort_by]) if params[:sort_by]
Nikoji, eto koji
User.noneNull objekt koji se dalje može ulančavati
I još
User.(metoda)!
I još
User.(metoda)!
@users = User.all@users = @users.where(name: params[:name]) if params[:name]@users = @users.order(params[:sort_by]) if params[:sort_by]
Prije:
I još
User.(metoda)!
@users = User.all@users = @users.where(name: params[:name]) if params[:name]@users = @users.order(params[:sort_by]) if params[:sort_by]
Prije:
@users = [email protected]!(name: params[:name]) if params[:name]@users.order!(params[:sort_by]) if params[:sort_by]
Sada:
ZBOGOM STVARI
Zbogom Ruby 1.8
Zbogomfind(:all, :conditions => ...)
ZbogomActiveRecord:SessionStore
ZbogomActiveResource
ZbogomRails::Plugin
ZbogomRails::Plugin
• u /lib folder • pretvori u gem
• Turbolinks• Cached schema dump• HTTP PATCH• HTML5 helperi• config.threadsafe!
Još STO stvari
• Rails 3.1 - gotov• Rails 3.2 - neka deprecation upozorenja, podrška do 4.1• Rails 4.0 - deprecation upozorenja• Rails 4.1 - uklanjanje deprecated dijelova
Verzioniranje
Kad izlazi?
http://edgeguides.rubyonrails.org/4_0_release_notes.html
Dodatna literatura
Rails 4.0 Mind mapBoston.rb - What to expect in Rails 4.0EdgeRails.info Bloghttps://github.com/rails/rails
Dodatna dodatna literatura
Pitanja?
Hvala na pažnji!