ActiveRecord Flashcards
Base: Rails creates Ruby ________ files in db/migrate
Rails creates Ruby migration files in db/migrate
Base: Subclass _________::Base to create __________
Subclass ActiveRecord::Base to create persistence
Base: rake db:migrate does the _________ migration
rake db:migrate does the database migration
Rake –tasks
$ rake –tasks
(in /Users/beaty-admin/Documents/DU/4585/demo)
rake about # List versions of all Rails frameworks and the env…
rake assets:clean # Remove compiled assets
rake assets:precompile # Compile all the assets named in config.assets.pre…
rake db:create # Create the database from DATABASE_URL or config/d…
rake db:drop # Drops the database using DATABASE_URL or the curr…
rake db:fixtures:load # Load fixtures into the current environment’s data…
rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE…
rake db:migrate:status # Display status of migrations
rake db:rollback # Rolls the schema back to the previous version (sp…
rake –tasks Continued
rake db:schema:dump # Create a db/schema.rb file that can be portably u…
rake db:schema:load # Load a schema.rb file into the database
rake db:seed # Load the seed data from db/seeds.rb
rake db:setup # Create the database, load the schema, and initial…
rake db:structure:dump # Dump the database structure to db/structure.sql
rake db:version # Retrieves the current schema version number
rake doc:app # Generate docs for the app – also available doc:r…
rake log:clear # Truncates all *.log files in log/ to zero bytes
rake middleware # Prints out your Rack middleware stack
rake notes # Enumerate all annotations (use notes:optimize, :f…
rake notes:custom # Enumerate a custom annotation, specify with ANNOT…
rake rails:template # Applies the template supplied by LOCATION=(/path/…
rake rails:update # Update configs and some other initially generated…
rake routes # Print out all defined routes in match order, with…
rake secret # Generate a cryptographically secure secret key (t…
rake stats # Report code statistics (KLOCs, etc) from the appl…
rake test # Runs test:units, test:functionals, test:integrati…
rake test:recent # Run tests for {:recent=>“test:prepare”} / Test re…
rake test:single # Run tests for {:single=>“test:prepare”}
rake test:uncommitted # Run tests for {:uncommitted=>“test:prepare”} / Te…
rake time:zones:all # Displays all time zones, also available: time:zon…
rake tmp:clear # Clear session, cache, and socket files from tmp/ …
rake tmp:create # Creates tmp directories for sessions, cache, sock…
Generated Additions:
•id
–Default primary ___
•id
–Default primary key
Generated Additions:
- created_at
- updated_at
- xxx_id
–Foreign keys
- created_at
- updated_at
- xxx_id
–Foreign keys
Primary keys:
•Can change
–self.primary_key = “column”
•Can change
–self.primary_key = “column”
Primary keys:
•Still use “id” to refer to primary key
•Still use “id” to refer to primary key
Relationships:
- Associations between ______
- One to ___
- One to ____
- Many to _____
- Associations between tables
- One to one
- One to many
- Many to many
One to One:
class Employee < ActiveRecord::Base
has_one :office
end
class Office < ActiveRecord::Base
belongs_to :employee
foreign key - employee_id
end
class Employee < ActiveRecord::Base
has_one :office
end
class Office < ActiveRecord::Base
belongs_to :employee
foreign key - employee_id
end
ERD:
Rule:
•The model that has the foreign key always has the belongs_to
•The model that has the foreign key always has the belongs_to
Generated Methods for belongs_to and has_one:
- other
- other=(other)
- build_other(attributes={})
- create_other(attributes={})
- create_other!(attributes={})
Generated Methods for belongs_to and has_one:
- other
- other=(other)
- build_other(attributes={})
- create_other(attributes={})
- create_other!(attributes={})
One to Many:
class Manager < ActiveRecord::Base
has_many :employees
end
class Employee < ActiveRecord::Base
belongs_to :manager
foreign key - manager_id
end
class Manager < ActiveRecord::Base
has_many :employees
end
class Employee < ActiveRecord::Base
belongs_to :manager
foreign key - manager_id
end
One to Many ERD:
So…
$ rails new advisorandstudent
$ cd advisorandstudent
$ rails generate scaffold Student name:string advisor:references
$ rails generate scaffold Advisor name:string
$ rails new advisorandstudent
$ cd advisorandstudent
$ rails generate scaffold Student name:string advisor:references
$ rails generate scaffold Advisor name:string
Modify:
- app/models/advisor.rb
- app/views/students/index.html.erb
- app/views/students/show.html.erb
- app/views/advisors/show.html.erb
- app/models/advisor.rb
- app/views/students/index.html.erb
- app/views/students/show.html.erb
- app/views/advisors/show.html.erb
Modify Advisor Model:
$ more app/models/advisor.rb
class Advisor < ActiveRecord::Base
has_many :students
end
$ more app/models/advisor.rb
class Advisor < ActiveRecord::Base
has_many :students
end
Modify Student Model (Maybe):
$ more app/models/student.rb
class Student < ActiveRecord::Base
belongs_to :advisor
end
$ more app/models/student.rb
class Student < ActiveRecord::Base
belongs_to :advisor
end
app/views/students/_form.html.erb:
[…]
<%= f.label :advisor_id %>
<%= f.select(:advisor_id,
options_from_collection_for_select(Advisor.all,
:id, :name)) %>
[…]
[…]
<%= f.label :advisor_id %>
<%= f.select(:advisor_id,
options_from_collection_for_select(Advisor.all,
:id, :name)) %>
[…]
app/views/students/index.html.erb:
app/views/advisors/show.html.erb:
Many to Many:
class Assignment < ActiveRecord::Base
belongs_to :programmer # foreign key - programmer_id
belongs_to :project # foreign key - project_id
end
class Programmer < ActiveRecord::Base
has_many :assignments
has_many :projects, through: :assignments
end
class Project < ActiveRecord::Base
has_many :assignments
has_many :programmers, through: :assignments
end
class Assignment < ActiveRecord::Base
belongs_to :programmer # foreign key - programmer_id
belongs_to :project # foreign key - project_id
end
class Programmer < ActiveRecord::Base
has_many :assignments
has_many :projects, through: :assignments
end
class Project < ActiveRecord::Base
has_many :assignments
has_many :programmers, through: :assignments
end
Many to Many ERD:
Join:
- Assignment model a join or junction table
- You have to create explicitly
- Assignment model a join or junction table
- You have to create explicitly
HABTM:
class Programmer < ActiveRecord::Base
has_and_belongs_to_many :projects
end
class Project < ActiveRecord::Base
has_and_belongs_to_many :programmers
end
class Programmer < ActiveRecord::Base
has_and_belongs_to_many :projects
end
class Project < ActiveRecord::Base
has_and_belongs_to_many :programmers
end
Join Table Model:
- You still have to create table
- Name must be named programmers_projects
–Lexical (alphabetic) order
•Before
$ rails generate model ProgrammersProjects programmer_id:integer project_id:integer
•Now:
$ rails generate model ProgrammersProjects programmer:references project:references
- You still have to create table
- Name must be named programmers_projects
–Lexical (alphabetic) order
•Before
$ rails generate model ProgrammersProjects programmer_id:integer project_id:integer
•Now:
$ rails generate model ProgrammersProjects programmer:references project:references
Basically:
- Create two models and a join table
- Update two models with HABTM
- Use select options similarly as before
- Iterate in show view using foreign key
- Create two models and a join table
- Update two models with HABTM
- Use select options similarly as before
- Iterate in show view using foreign key
Basically Continued:
- Add foreign key to permit in controller
- That’s it
–Conventions take care of all the insertions into the join table
- Add foreign key to permit in controller
- That’s it
–Conventions take care of all the insertions into the join table
Create:
$ rails new bookslibraries
$ cd bookslibraries
$ rails generate scaffold Book name:string
$ rails generate scaffold Library name:string
$ rails generate model BooksLibraries book:references library:references
$ rake db:migrate
$ rails new bookslibraries
$ cd bookslibraries
$ rails generate scaffold Book name:string
$ rails generate scaffold Library name:string
$ rails generate model BooksLibraries book:references library:references
$ rake db:migrate
app/controllers/books_controller.rb
— a/app/controllers/books_controller.rb
+++ b/app/controllers/books_controller.rb
@@ -15,10 +15,12 @@ class BooksController < ApplicationController
GET /books/new
def new
@book = Book.new
+ @libraries = Library.all
end
GET /books/1/edit
def edit
+ @libraries = Library.all
end
POST /books
@@ -69,6 +71,6 @@ class BooksController < ApplicationController
Never trust parameters from the scary internet, only allow the white list through.
def book_params
- params.require(:book).permit(:name)
+ params.require(:book).permit(:name, :library_ids => [])
end
end
— a/app/controllers/books_controller.rb
+++ b/app/controllers/books_controller.rb
@@ -15,10 +15,12 @@ class BooksController < ApplicationController
GET /books/new
def new
@book = Book.new
+ @libraries = Library.all
end
GET /books/1/edit
def edit
+ @libraries = Library.all
end
POST /books
@@ -69,6 +71,6 @@ class BooksController < ApplicationController
Never trust parameters from the scary internet, only allow the white list through.
def book_params
- params.require(:book).permit(:name)
+ params.require(:book).permit(:name, :library_ids => [])
end
end
app/controllers/libraries_controller.rb
— a/app/controllers/libraries_controller.rb
+++ b/app/controllers/libraries_controller.rb
@@ -15,10 +15,12 @@ class LibrariesController < ApplicationController
GET /libraries/new
def new
@library = Library.new
+ @books = Book.all
end
GET /libraries/1/edit
def edit
+ @books = Book.all
end
POST /libraries
@@ -69,6 +71,6 @@ class LibrariesController < ApplicationController
Never trust parameters from the scary internet, only allow the white list through.
def library_params
- params.require(:library).permit(:name)
+ params.require(:library).permit(:name, :book_ids => [])
end
end
— a/app/controllers/libraries_controller.rb
+++ b/app/controllers/libraries_controller.rb
@@ -15,10 +15,12 @@ class LibrariesController < ApplicationController
GET /libraries/new
def new
@library = Library.new
+ @books = Book.all
end
GET /libraries/1/edit
def edit
+ @books = Book.all
end
POST /libraries
@@ -69,6 +71,6 @@ class LibrariesController < ApplicationController
Never trust parameters from the scary internet, only allow the white list through.
def library_params
- params.require(:library).permit(:name)
+ params.require(:library).permit(:name, :book_ids => [])
end
end
app/models/book.rb and app/models/library.rb:
— a/app/models/book.rb
+++ b/app/models/book.rb
@@ -1,2 +1,3 @@
class Book < ActiveRecord::Base
+ has_and_belongs_to_many :libraries
end
— a/app/models/library.rb
+++ b/app/models/library.rb
@@ -1,2 +1,3 @@
class Library < ActiveRecord::Base
+ has_and_belongs_to_many :books
end
— a/app/models/book.rb
+++ b/app/models/book.rb
@@ -1,2 +1,3 @@
class Book < ActiveRecord::Base
+ has_and_belongs_to_many :libraries
end
— a/app/models/library.rb
+++ b/app/models/library.rb
@@ -1,2 +1,3 @@
class Library < ActiveRecord::Base
+ has_and_belongs_to_many :books
end
app/views/books/_form.html.erb:
— a/app/views/books/_form.html.erb
+++ b/app/views/books/_form.html.erb
@@ -15,6 +15,11 @@
<%= f.label :name %>
<%= f.text_field :name %>
+
+ <%= f.label :library_id %>
+ <%= f.collection_check_boxes(:library_ids, @libraries, :id, :name) %>
+
+
<%= f.submit %>
— a/app/views/books/_form.html.erb
+++ b/app/views/books/_form.html.erb
@@ -15,6 +15,11 @@
<%= f.label :name %>
<%= f.text_field :name %>
+
+ <%= f.label :library_id %>
+ <%= f.collection_check_boxes(:library_ids, @libraries, :id, :name) %>
+
+
<%= f.submit %>
app/views/books/_form.html.erb:
— a/app/views/books/_form.html.erb
+++ b/app/views/books/_form.html.erb
@@ -15,6 +15,11 @@
<%= f.label :name %>
<%= f.text_field :name %>
+
+ <%= f.label :library_id %>
+ <%= f.collection_check_boxes(:library_ids, @libraries, :id, :name) %>
+
+
<%= f.submit %>
— a/app/views/books/_form.html.erb
+++ b/app/views/books/_form.html.erb
@@ -15,6 +15,11 @@
<%= f.label :name %>
<%= f.text_field :name %>
+
+ <%= f.label :library_id %>
+ <%= f.collection_check_boxes(:library_ids, @libraries, :id, :name) %>
+
+
<%= f.submit %>
app/views/books/show.html.erb:
— a/app/views/books/show.html.erb
+++ b/app/views/books/show.html.erb
@@ -5,5 +5,11 @@
<%= @book.name %>
+
+ <% @book.libraries.each do |library| %>
+
- <%= library.name %>
+ <% end %>
+
+
<%= link_to ‘Edit’, edit_book_path(@book) %> |
<%= link_to ‘Back’, books_path %>
— a/app/views/books/show.html.erb
+++ b/app/views/books/show.html.erb
@@ -5,5 +5,11 @@
<%= @book.name %>
+
+ <% @book.libraries.each do |library| %>
+
- <%= library.name %>
+ <% end %>
+
+
<%= link_to ‘Edit’, edit_book_path(@book) %> |
<%= link_to ‘Back’, books_path %>
app/views/libraries/_form.html.erb
app/views/libraries/show.html.erb
Accessing Data:
•.find(id)
–.find(id,id,…)
•Dynamic finder
–Student.find_by_name (“Steve Beaty”)
–Student.find_last_by_name (“Steve Beaty”)
–Student.find_all_by_name (“Steve Beaty”)
–
•.find(id)
–.find(id,id,…)
•Dynamic finder
–Student.find_by_name (“Steve Beaty”)
–Student.find_last_by_name (“Steve Beaty”)
–Student.find_all_by_name (“Steve Beaty”)
–
More Dynamic:
- Student.find_by_name_and_email(“Steve Beaty”, “steven.beaty@du.edu”)
- Student.find_by_name!(“Steve Beaty”)
- Raises exception if not found
- Instead of returning nil
- find_or_initialize_by_()
- find_or_create_by_()
- Student.find_by_name_and_email(“Steve Beaty”, “steven.beaty@du.edu”)
- Student.find_by_name!(“Steve Beaty”)
- Raises exception if not found
- Instead of returning nil
- find_or_initialize_by_()
- find_or_create_by_()
Embedding SQL:
•Students.where([“name = ? and major = ‘cs’”, name])
–Cleans up SQL to avoid injections
•Where takes a hash
–Student.where(params[:order])
•Students.where([“name = ? and major = ‘cs’”, name])
–Cleans up SQL to avoid injections
•Where takes a hash
–Student.where(params[:order])
Like, SQL:
- Student.where(“name like ?”, “Steve%”)
- Student.where(name: ‘Steve’).order(“GPA”)
- Student.where(name: ‘Steve’).limit(10)
- Student.where(name: ‘Steve’).select(“name, GPA”)
- Can also specify joins
- Student.where(“name like ?”, “Steve%”)
- Student.where(name: ‘Steve’).order(“GPA”)
- Student.where(name: ‘Steve’).limit(10)
- Student.where(name: ‘Steve’).select(“name, GPA”)
- Can also specify joins
Column Operations:
•Student.average(:GPA)
–.maximum, .minimum, .sum, .count
•Student.group(:state).average(:GPA)
–Average GPA per state
•Student.average(:GPA)
–.maximum, .minimum, .sum, .count
•Student.group(:state).average(:GPA)
–Average GPA per state
Scopes:
•Create a scope of “where”s to operate on
class Student
scope :deans_list, lambda {|gpa| where(‘GPA > 3.5’, gpa)}
end
•Create a scope of “where”s to operate on
class Student
scope :deans_list, lambda {|gpa| where(‘GPA > 3.5’, gpa)}
end
Bang!
- .save returns true if record saved, nil otherwise
- .save! raises exception if not saved
- .create always return ActiveRecord object, saved or not
- .create! raises exception
- .save returns true if record saved, nil otherwise
- .save! raises exception if not saved
- .create always return ActiveRecord object, saved or not
- .create! raises exception
Removing Data:
- .delete
- .destroy
–Does a delete and then freezes object
–Use destroy in most cases
- .delete
- .destroy
–Does a delete and then freezes object
–Use destroy in most cases
Callbacks:
- One can inject code at various stages of save and destroy (but not delete)
- Can help keep model data clean
- One can inject code at various stages of save and destroy (but not delete)
- Can help keep model data clean
Callbacks Continued:
•Before and after
–Validation
–Save
–Create
–Update
–Destroy
•Also after_find and after_initialize
•Before and after
–Validation
–Save
–Create
–Update
–Destroy
•Also after_find and after_initialize
Validation:
class CreditCard < ActiveRecord::Base
Strip everything but digits, so the user can specify “555 234 34” or
“5552-3434” and both will mean “55523434”
before_validation(on: :create) do
self.number = number.gsub(/[^0-9]/, “”) if attribute_present?(“number”)
end
end
class CreditCard < ActiveRecord::Base
Strip everything but digits, so the user can specify “555 234 34” or
“5552-3434” and both will mean “55523434”
before_validation(on: :create) do
self.number = number.gsub(/[^0-9]/, “”) if attribute_present?(“number”)
end
end
Private Method Callback:
class Subscription < ActiveRecord::Base
before_create :record_signup
private
def record_signup
self.signed_up_on = Date.today
end
end
class Subscription < ActiveRecord::Base
before_create :record_signup
private
def record_signup
self.signed_up_on = Date.today
end
end
Doco:
- http://api.rubyonrails.org/
- rdoc
$ cd /usr/local/rvm/gems/ruby-1.9.3-p392/gems
$ rdoc
$ open doc/index.html
- http://api.rubyonrails.org/
- rdoc
$ cd /usr/local/rvm/gems/ruby-1.9.3-p392/gems
$ rdoc
$ open doc/index.html