w3d3 Flashcards

1
Q

In Rails, how do you configure a database and create it?

A

Edit it in config/database.yml, then run rake db:create

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is a migration?

A

A file containing Ruby code that describes a set of changes applied to the database

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

When making a class that handles a migration, what must it inherit from?

A

ActiveRecord::Migration

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

In ActiveRecord::Migration, what does ‘string’ refer to?

A

VARCHAR(255)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is ActiveRecord::Migrations#change do, and how does it relate to #up and #down?

A

change can migrate or rollback a database. #up calls change to migrate, #down calls change to rollback.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Where are migration files stored?

A

db/migrate

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What exactly does db:migrate do?

A

It finds unexecuted migrations, then runs their up or change methods.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Where does Rails store information about which migrations have been run?

A

In a table called schema_migrations.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

T/F: After you run a migration, you can edit the migration and then run it again.

A

F; you must rollback the db and run the migration again; Rails will already think you ran the migration and will not run it again otherwise. YOU SHOULD ROLLBACK FIRST AND THEN EDIT THE MIGRATION, b/c otherwise Rails will try to roll back the db in its current version, which may not be compatible.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

When should you ever edit an existing migration?

A

When it has never been run and/or pushed to git.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Where can you see the current state of your db’s schema?

A

db/schema.rb

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is an ORM?

A

An object relational mapping is the system that translates between SQL records and Ruby (or Java, or Lisp…) objects. The ActiveRecord ORM translates rows from your SQL tables into Ruby objects on fetch, and translates your Ruby objects back to rows on save.

In essence, it allows Ruby objects to interact with a db.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

For each table in the db, what is defined?

A

A model (given the singular name of the table). Each instance of the model class represents a row in the db. All of these classes inherit from ActiveRecord::Base

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

T/F: Ruby automatically distinguishes between the plural name of a db and the singular name of a model.

A

T; it recognizes the relation and associates them.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What do ActiveRecord::Base::find and ActiveRecord::Base::all do?

A

::all returns all objects of the model that are in the table (one instance per row)

::find takes an integer argument, and finds the object whose primary key is the argument.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What does ActiveRecord::Base::where do?

A

It turns the string arguments given into a WHERE clause, then retrieves the filtered list of objects.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

How does the following syntax avoid an SQL injection attack:

Physician.where(“home_city = ?”, “La Jolla”)

A

It uses the value “La Jolla” to stand in for the ‘?’ in the first string argument. It escapes every character in “La Jolla” to avoid it being interpreted as malicious code (if it’s given)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What is an alternate way to pass a SQL fragment?

A

Physician.where(:college => [“City College”, “Columbia”, “NYU”])

Physician.where(:years_experience => (3..9))

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

T/F: ActiveRecord::Base will give each model class attr_accessors for each column

A

T

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

After we make changes to a model instance, how can we save those changes (read: change the corresponding row)?

A

Call #save! on the instance

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

How can we remove an instance (row) from the db altogether?

A

Call #destroy on the instance

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

How do we declare associations?

A

Use belongs_to and has_many

class Course < ActiveRecord::Base
  belongs_to(
    :professor,
    :class_name => "Professor",
    :foreign_key => :professor_id,
    :primary_key => :id
  )
end
class Professor < ActiveRecord::Base
  has_many(
    :courses,
    :class_name => "Course",
    :foreign_key => :professor_id,
    :primary_key => :id
  )
end
23
Q

What do associations let us do?

A

Allow instance method macros for SQL fragments:

course.professor # the professor for a course
# => SELECT
#      professors.*
#    FROM
#      professors
#    WHERE
#      professors.id = ?
#    LIMIT
#      1
#
# The `?` is filled with `course.professor_id`; the LIMIT it not strictly
# necessary, but expresses the intent that one record be returned.
professor.courses # an array of the courses a professor teaches
# => SELECT
#      courses.*
#    FROM
#      courses
#    WHERE
#      courses.professor_id = ?
#
# The `?` is filled with `professor.id`.
24
Q

What exactly does belongs_to do?

A

Associates the foreign key to a matching primary key:

class Order < ActiveRecord::Base
  belongs_to :customer
end

This sets up an association between the foreign key ‘customer_id’ column in orders and the primary key ‘id’ in customers

25
Q

What exactly does has_many do?

A

Associates the primary key to the matching foreign key:

class Customer < ActiveRecord::Base
has_many :orders
end

This sets up an association between the primary key (‘id’) in customers with the foreign key ‘customer_id’ in orders

26
Q

What is the rule to decide whether to use belongs_to or has_many

A

If the record is pointed to by the associated records

The choice is about who has the foreign key and who has the primary key. It is not really about whether there is at most one or potentially multiple associated records.

Think about the SQL that will be generated; that is the shortcut that these macros will produce!

27
Q

What should we do about N+1 (iterative) queries?

A

AVOID THEM!

28
Q

What is has_many :through, and how do we use it?

A

It allows us to declare associations THROUGH tables:

has_many :patients, :through => :appointments, :source => :patient

A has_many :through association simply names two existing associations and links them up. :through is step 1, :source is step 2

Low-level details (foreign/primary keys) are not relevant.

This is the underlying SQL (not sure if it is reversed or not lol):

physician.patients
# SELECT
#  patients.*
# FROM
#  appointments
# JOIN
#  patients ON appointments.patient_id = patients.id
# WHERE
#  appointments.physician_id = ?
29
Q

Explain has_one

A

Returns the associated object (assuming an association already exists)

30
Q

When would you use has one :through

A

When you want to link a belongs_to and a has_one association.

31
Q

What are Rails naming conventions for Models & Tables?

A

The Model/Class is CamelCased, capitalized, and singularized.

The table/schema is lower case, snake_cased, and pluralized.

32
Q

What are Rails naming conventions for foreign and primary keys?

A

Foreign key columns should be named after the table they refer to. For instance, if an Appointment has a column that refers to a Physician, it should be named physician_id.

By default, Active Record will use an integer column named id as the table’s primary key. When using Rails Migrations to create your tables, this column will be automatically created.

33
Q

What is a reflexive association? What naming conventions should you adopt when making one.

A

An association between a table and a reference back to itself (a self JOIN).

To avoid confusion for you and Rails, it is OK to break convention and use aliases:

class Employee < ActiveRecord::Base
  has_many :subordinates, 
           :class_name => "Employee",
           :foreign_key => :manager_id,
           :primary_key => :id
  belongs_to :manager, 
             :class_name => "Employee",
             :foreign_key => :manager_id,
             :primary_key => :id
end
34
Q

What is a validation in Rails?

A

A check to ensure that objects are correctly filled out before they are saved to the db. Validations keep garbage data out.

35
Q

Why are validations SO important for security?

A

They keep bad data, or even potentially malicious code, out.

36
Q

What should constraints implemented by the db be reserved for?

A

Serious software bugs; the unhandled exception generated by them is inappropriate for validating user input.

Having said that, db constraints like NOT NULL are useful to catch errors outside of the Rails scope as a last line of defense.

37
Q

What are model-level validations?

A

Validations written in Ruby, implemented at the Rails (not the db) level.

38
Q

When do validations happen?

A

Whenever you call the save/save! methods; save will return a boolean as to its success, whereas save! will raise an error if the validations fail.

save/save! will not perform INSERT/UPDATE operations if the validations fail.

39
Q

What is the method that calls validations?

A

valid?

40
Q

What is the syntax to declare validations?

A
class Person < ActiveRecord::Base
  validates :name, :presence => true
end

Person.create(:name => “John Doe”).valid? # => true
Person.create(:name => nil).valid? # => false

41
Q

What is #errors and when should we use it?

A

Use it AFTER validations are run; it returns a hash-like object (an instance of ActiveModel::Errors) where the keys are attributes and the values are the errors for each attribute.

42
Q

How can we get #errors to print out human-readable messages?

A

errors.full_messages

43
Q

What is the presence validator used for?

A

It validates that the specified attributes are not empty. It calls #blank? to ensure that a string is neither nil nor a blank string.

class Person < ActiveRecord::Base
  # must have name, login, and email
  validates :name, :login, :email, :presence => true
end
44
Q

How can we check for the presence of an associated object?

A
class LineItem < ActiveRecord::Base
  belongs_to :order

validates :order, :presence => true
end

45
Q

What does the uniqueness validator do?

A

Ensures that the attributes value is unique (within the table column)

class Account < ActiveRecord::Base
  # no two Accounts with the same email
  validates :email, :uniqueness => true
end
46
Q

What does the :scope option do for uniqueness?

A

It specifies the amount of uniqueness.

class Holiday < ActiveRecord::Base
# no two Holidays with the same name for a single year
validates :name, :uniqueness => {
:scope => :year,
:message => “should happen once per year”
}
end

47
Q

How can you write your own custom validation?

A
class Invoice < ActiveRecord::Base
  # validate tells the class to run these methods at validation time.
  validate :discount_cannot_be_greater_than_total_value

private
def discount_cannot_be_greater_than_total_value
if discount > total_value
errors[:discount] &laquo_space;“can’t be greater than total value”
end
end
end

48
Q

When should you write a custom validator class?

A

When you want to reuse validation logic for multiple models.

49
Q

What must a custom validator class have?

A

A validate_each method which takes three arguments: the record, the attribute name and its value:

# app/validators/email_validator.rb
class EmailValidator < ActiveModel::EachValidator
  CRAZY_EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i

def validate_each(record, attribute_name, value)
unless value =~ CRAZY_EMAIL_REGEX
# we can use EachValidator#options to access custom options
# passed to the validator.
message = options[:message] || “is not an email”
record.errors[attribute_name] &laquo_space;message
end
end
end

# app/models/person.rb
class Person < ActiveRecord::Base
  # Rails knows `:email` means `EmailValidator`.
  validates :email, :presence => true, :email => true
  # not required, but must also be an email
  validates :backup_email, :email => {:message => "isn't even valid"}
end
50
Q

Why should you enforce length validations at the AR (ActiveRecord) level?

A

B/C if the db throws a VARCHAR length error, then you will get a crash.

some urls get mighty long
t.string :url, :limit => 1024
# some people go on and on…
t.text :comments

51
Q

What do the :allow_nil and :allow_blank validation helpers do?

A

The :allow_nil option skips the validation when the value being validated is nil.

class Coffee < ActiveRecord::Base
  validates :size, :inclusion => { :in => %w(small medium large),
    :message => "%{value} is not a valid size" }, :allow_nil => true
end

:allow_blank allows for an empty string to pass validation.

class Topic < ActiveRecord::Base
  validates :title, :length => { :is => 5 }, :allow_blank => true
end

Topic.create(“title” => “”).valid? # => true
Topic.create(“title” => nil).valid? # => true

52
Q

How can you provide a custom error message for a failed validation?

A

Use the :message option.

53
Q

How should you use the :if and :unless validation predicates?

A

To specify when the validation should happen:

class Order < ActiveRecord::Base
  validates :card_number, :presence => true, :if => :paid_with_card?

def paid_with_card?
payment_type == “card”
end
end

54
Q

What is an index, when should we use one, and why are they important?

A

An index allows us to avoid costly full-table scans by giving us a specific value to lookup. They are especially useful when trying to reverse a has_many query:

class User < ActiveRecord::Base
has_many :conversations
end

class Conversation < ActiveRecord::Base
  belongs_to :user
end   
class AddUserIdIndexToConversations < ActiveRecord::Migration
  def change
    add_index :conversations, :user_id
  end
end