Upgrade to Pro — share decks privately, control downloads, hide ads and more …

New Stuff in Rails 4

New Stuff in Rails 4

Sandbox Rails 4 demo project I've used for this presentation is here:
https://github.com/gregmalcolm/rails4demo

Greg Malcolm

October 21, 2013
Tweet

More Decks by Greg Malcolm

Other Decks in Programming

Transcript

  1. or

  2. Moved to Gem-space • Mass assignment • ActiveRecord::SessionStore • Action

    Caching, Page Caching, Cashew Cashing • Observers • ActiveResource • Sprockets
  3. Moved to Gem-space • Mass assignment • ActiveRecord::SessionStore • Action

    Caching, Page Caching, Cashew Cashing • Observers • ActiveResource • Sprockets
  4. ActiveModel class Tardis! include ActiveModel::Validations! include ActiveModel::Conversion! extend ActiveModel::Naming! !

    attr_accessor :doctor, ! :companion, ! :theme! ! def initialize(attributes = {})! attributes.each do |k, v|! send(“#{k}=”, v)! end! end! end Rails 3:
  5. ActiveModel::Model class Tardis! include ActiveModel::Model! ! attr_accessor :doctor, ! :companion,

    ! :theme! ! validates :doctor, presence: true! validates :companion, length: { maximum: 20 }! end
  6. Finders ‘all’ is scopey now 2.0.0p0 :037 > Wizard.all.last! Wizard

    Load (0.8ms) SELECT "wizards".* FROM "wizards" ORDER BY "wizards"."id" DESC LIMIT 1! => #<Wizard id: 7, name: "Bellatrix", alignment: "evil", spells: ["Avada Kedavra", "Accio"], bag_of_holding: nil, created_at: "2013-07-25 04:10:36", updated_at: "2013-07-25 04:10:36">
  7. class WizardsController < ApplicationController! before_action :set_wizard, only: [:show, :edit, :update,

    :destroy]! ! ...! ! # PATCH/PUT /wizards/1! # PATCH/PUT /wizards/1.json! def update! respond_to do |format|! if @wizard.update(wizard_params)! format.html { redirect_to @wizard, notice: 'Wizard was successfully updated.' }! format.json { head :no_content }! else! format.html { render action: 'edit' }! format.json { render json: @wizard.errors, status: :unprocessable_entity }! end! end! end! ! ...! ! private! # Use callbacks to share common setup or constraints between actions.! def set_wizard! @wizard = Wizard.find(params[:id])! end! ! # Never trust parameters from the scary internet, only allow the white list through.! def wizard_params! params.require(:wizard).permit(:name, :alignment, :spells, :bag_of_holding)! end! end
  8. class WizardsController < ApplicationController! before_action :set_wizard, only: [:show, :edit, :update,

    :destroy]! ! ...! ! # PATCH/PUT /wizards/1! # PATCH/PUT /wizards/1.json! def update! respond_to do |format|! if @wizard.update(wizard_params)! format.html { redirect_to @wizard, notice: 'Wizard was successfully updated.' }! format.json { head :no_content }! else! format.html { render action: 'edit' }! format.json { render json: @wizard.errors, status: :unprocessable_entity }! end! end! end! ! ...! ! private! # Use callbacks to share common setup or constraints between actions.! def set_wizard! @wizard = Wizard.find(params[:id])! end! ! # Never trust parameters from the scary internet, only allow the white list through.! def wizard_params! params.require(:wizard).permit(:name, :alignment, :spells, :bag_of_holding)! end! end
  9. class WizardsController < ApplicationController! before_action :set_wizard, only: [:show, :edit, :update,

    :destroy]! ! ...! ! # PATCH/PUT /wizards/1! # PATCH/PUT /wizards/1.json! def update! respond_to do |format|! if @wizard.update(wizard_params)! format.html { redirect_to @wizard, notice: 'Wizard was successfully updated.' }! format.json { head :no_content }! else! format.html { render action: 'edit' }! format.json { render json: @wizard.errors, status: :unprocessable_entity }! end! end! end! ! ...! ! private! # Use callbacks to share common setup or constraints between actions.! def set_wizard! @wizard = Wizard.find(params[:id])! end! ! # Never trust parameters from the scary internet, only allow the white list through.! def wizard_params! params.require(:wizard).permit(:name, :alignment, :spells, :bag_of_holding)! end! end
  10. class WizardsController < ApplicationController! before_action :set_wizard, only: [:show, :edit, :update,

    :destroy]! ! ...! ! # PATCH/PUT /wizards/1! # PATCH/PUT /wizards/1.json! def update! respond_to do |format|! if @wizard.update(wizard_params)! format.html { redirect_to @wizard, notice: 'Wizard was successfully updated.' }! format.json { head :no_content }! else! format.html { render action: 'edit' }! format.json { render json: @wizard.errors, status: :unprocessable_entity }! end! end! end! ! ...! ! private! # Use callbacks to share common setup or constraints between actions.! def set_wizard! @wizard = Wizard.find(params[:id])! end! ! # Never trust parameters from the scary internet, only allow the white list through.! def wizard_params! params.require(:wizard).permit(:name, :alignment, :spells, :bag_of_holding)! end! end
  11. class WizardsController < ApplicationController! before_action :set_wizard, only: [:show, :edit, :update,

    :destroy]! ! ...! ! # PATCH/PUT /wizards/1! # PATCH/PUT /wizards/1.json! def update! respond_to do |format|! if @wizard.update(wizard_params)! format.html { redirect_to @wizard, notice: 'Wizard was successfully updated.' }! format.json { head :no_content }! else! format.html { render action: 'edit' }! format.json { render json: @wizard.errors, status: :unprocessable_entity }! end! end! end! ! ...! ! private! # Use callbacks to share common setup or constraints between actions.! def set_wizard! @wizard = Wizard.find(params[:id])! end! ! # Never trust parameters from the scary internet, only allow the white list through.! def wizard_params! params.require(:wizard).permit(:name, :alignment, :spells, :bag_of_holding)! end! end
  12. Postgres class SetupHstore < ActiveRecord::Migration def self.up execute "create extension

    hstore" end ! def self.down execute "drop extension hstore" end end
  13. Postgres class SetupHstore < ActiveRecord::Migration def self.up #execute "create extension

    hstore" system("psql template1 -c 'create extension hstore;'") end ! def self.down #execute "drop extension hstore" system("psql template1 -c 'drop extension hstore;'") end end
  14. Postgres class CreateWizards < ActiveRecord::Migration def change create_table :wizards do

    |t| t.string :name t.string :alignment t.string :spells, array:true t.hstore :bag_of_holding ! t.timestamps end end end
  15. Postgres Wizard.create name: 'Bellatrix', alignment: 'evil', spells: ['Avada Kedavra', 'Accio'],

    bag_of_holding: { wand: 'goose bone' } ! Wizard.create name: 'Evil Willow', alignment: 'evil', spells: ['Sphere of Infinite Agonies', 'Living Flame', 'Vine Bondage'], bag_of_holding: { wand: 'unicorn tears', toothbrush: 'evil' }
  16. Postgres HStore Queries Who has a wand? Wizard.where("bag_of_holding ? 'wand'")

    Who has a specific wand? Wizard.where("bag_of_holding -> 'wand' like 't%'")