Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Active record basics

1,075 views

Published on

RORLab BiWeekly Lecture 78 ~ 81
- Active Record Basics

[Screen Casts]
- Active Record Basics (1) : http://youtu.be/cqhZNvRDUXc
- Active Record Basics (2) : http://youtu.be/vpm6QoO5cYQ
- Active Record Basics (3) : http://youtu.be/Yon0dj-bIQI
- Active Record Basics (4) : http://youtu.be/4gh7mtNB7oc

* 스크린 캐스트 정보
- 주최 : Ruby On Rails Korea(https://www.facebook.com/groups/rubyonrailskorea/)
- 후원 : Naver D2(https://www.facebook.com/naverd2)

Published in: Technology
  • Be the first to comment

Active record basics

  1. 1. Active Record Basics RoRLabBiWeeklyLecture 남승균 - RoR Lab
  2. 2. 모든 초고는 쓰레기다 - 어네스트 헤밍웨이 2/72
  3. 3. 먼저 소설가가 되어야만 소설을 쓸 수 있는 게 아니라 먼저 뭔가를 써야만 소설가가 될 수 있다. - 김연수, <소설가의 일> 중 3/72
  4. 4. '초고' -> '처음 작성한 코드' '소설' -> '프로그램(코드)' '소설가' -> '프로그래머'로 치환하면? 작동하는 코드를 만들고, 그 코드를 점진적으로 개선하는 일 - <프로그래머(개발자)의 일> 4/72
  5. 5. Agenda Active Record: Introduction Creating Active Record Model CRUD: Reading and Writing Data Convention in Active Record Overriding the Naming Conventions Migrations : 살짝 맛보기 Validations : 살짝 맛보기 Callbacks : 살짝 맛보기 · · · · · · · · 5/72
  6. 6. Active Record: Introduction What is Active Record Rails MVC 중 'M(Model)'의 역할을 담당 비즈니스 데이터와 로직을 다루는 역할을 하는 시스템 레이어 ORM(Object Relational Mapping)의 Active Record 패턴을 구현한 구현체 · · · 6/72
  7. 7. Active Record: Introduction The Active Record Pattern Patterns of Enterprise Application Architecture, by Martin Fowler Data와 Behavior를 Object가 보유, 관리 + Data access logic을 도메인 오브젝트가 수행 · · 7/72
  8. 8. Active Record: Introduction as an ORM Framework 표현(Represents): 검증(Validates): 수행(Performs): · 모델(Model)과 데이터를 표현 모델간의 연관관계(associations)를 표현 관련 모델을 통한 상속 계층(inheritance hierachies)를 표현 · · · · 데이터베이스에 저장하기 전 모델을 검증· · 객체지향(Object-Oriented) 방식으로 데이터베이스 명령을 수행· 8/72
  9. 9. ORM Huddle ORM frameworks need A lot of "CONFIGURATION CODE" in general 9/72
  10. 10. Solution Rails Way Convention over Configuration Follow the conventions adopted by Rails very little configuration no configuration in some case · · 10/72
  11. 11. Creating Active Record Model Preparing MySQL Database CREATE DATABASE ar_basics_development; CREATE TABLE products ( id int(11) NOT NULL auto_increment, name varchar(255), vender varchar(255), PRIMARY KEY (id) ) SQL Table 명이 products (복수형: Plural Form)인 것에 유의 Naming Convention과 Customizing은 뒤에서 다룰 예정 · · 11/72
  12. 12. Creating Active Record Model Preparing Rails Application rails new ar_basics SHELL # in config/database.yml development: adapter: mysql2 encoding: utf8 database: ar_basics_development username: root password: YML 12/72
  13. 13. Creating Active Record Model Comnecting to MySQL # in Gemfile gem "mysql2" bundle install SHELL 13/72
  14. 14. Creating Active Record Model Creating Model # in app/models/product.rb class Product < ActiveRecord::Base end RUBY Model 명이 product (단수형: Singular Form)인 것에 유의· 14/72
  15. 15. CRUD: Reading and Writing Data Running Rails Console # in {RAILS_ROOT} rails console # or rails c SHELL 레일스 애플리케이션과 상호작용 웹사이트를 이용하지 않고 서버의 데이터를 빠르게 변경 · · 15/72
  16. 16. CRUD: Reading and Writing Data Create # Using create method product = Product.create(name: "iPhone 6", vender: "Apple") RUBY 새 모델을 만들어 반환 데이터베이스에 저장 · · 16/72
  17. 17. CRUD: Reading and Writing Data Create # Using new method product = Product.new product.name = "iPhone 6" product.vender = "Apple" product.save RUBY 새 모델을 만들어 반환 save 메서드가 호출되기 전까지는 데이터베이스에 저장되지 않음 · · 17/72
  18. 18. CRUD: Reading and Writing Data Create # Using new method with block product = Product.new do |p| p.name = "iPhone 6" p.vender = "Apple" end product.save RUBY 새 모델을 만들어 반환 save 메서드가 호출되기 전까지는 데이터베이스에 저장되지 않음 · · 18/72
  19. 19. CRUD: Reading and Writing Data Read # return a collection with all products products = Product.all RUBY # => equivalent to: SELECT `products`.* FROM `products` SQL products 테이블 내 모든 데이터 컬렉션을 반환· 19/72
  20. 20. CRUD: Reading and Writing Data Read count = Product.count RUBY # => equivalent to: SELECT COUNT(*) FROM `products` SQL products 테이블 데이터 개수를 반환· 20/72
  21. 21. CRUD: Reading and Writing Data Read # return the first product product = Product.first RUBY # => equivalent to: SELECT `products`.* FROM `products` ORDER BY `products`.`id` ASC LIMIT 1 SQL products 테이블 내 첫 번째 데이터를 반환 ORDER BY id ASC · · 21/72
  22. 22. CRUD: Reading and Writing Data Read # return the last product product = Product.last RUBY # => equivalent to: SELECT `products`.* FROM `products` ORDER BY `products`.`id` DESC LIMIT 1 SQL products 테이블 내 마지막 데이터를 반환 ORDER BY id DESC · · 22/72
  23. 23. CRUD: Reading and Writing Data Read # Using find method product = Product.find(1) RUBY # => equivalent to: SELECT `products`.* FROM `products` WHERE `products`.`id` = 1 LIMIT 1 SQL products 테이블 내 Primary Key 가 1인 레코드 불러오기· 23/72
  24. 24. CRUD: Reading and Writing Data Read # using find_by_{column_name} method iphone6 = Product.find_by_name('iPhone 6') RUBY # => equivalent to: SELECT `products`.* FROM `products` WHERE `products`.`name` = 'iPhone 6' LIMIT 1 SQL name이 'iPhone 6'인 레코드 중 첫 번째 것을 가져옴 · · 24/72
  25. 25. CRUD: Reading and Writing Data Read # using where and order clause apple_products = Product.where(vender: 'Apple').order("name ASC") RUBY # => equivalent to: SELECT `products`.* FROM `products` WHERE `products`.`vender` = 'Apple' ORDER BY name ASC SQL vender가 'Apple'인 레코드 컬렉션을 name 컬럼의 오름차순(ASC)으로 가져옴 · · 25/72
  26. 26. Further Reading: Active Record Query Interface 26/72
  27. 27. CRUD: Reading and Writing Data Wait... We need price column on products table ALTER TABLE products ADD COLUMN price int(11); SQL 27/72
  28. 28. CRUD: Reading and Writing Data Update iphone6 = Product.find_by_name('iPhone 6') iphone6.price = 850000 iphone6.save RUBY name이 'iPhone 6'인 첫 번째 레코드를 불러 와서 price 컬럼을 850000으로 설정하고 저장 · · · 28/72
  29. 29. CRUD: Reading and Writing Data Update iphone6 = Product.find_by_name('iPhone 6') iphone6.update(price: 850000) RUBY update 메서드를 이용하는 방법· 29/72
  30. 30. CRUD: Reading and Writing Data Bulk Update using update_all method Product.update_all "price = price + 50000" RUBY products 테이블 내 모든 레코드의 price를 50000원 인상 · · 30/72
  31. 31. CRUD: Reading and Writing Data Delete product = Product.find_by_name('iPhone 6') product.destroy RUBY name이 'iPhone 6'인 첫 번째 레코드를 불러 와서 삭제 · · 31/72
  32. 32. Live Coding 32/72
  33. 33. Convention in Active Record Naming Convention Table (Database) - 언더스코어(_)로 단어 사이를 구분한 복수형 Model (Class) - 각 단어의 첫 문자를 대문자로 표기한 단수형 · · 33/72
  34. 34. Convention in Active Record Naming Convention - By Example Model / Class Table / Schema Post posts BookClub book_clubs Deer deer Mouse mice Person people 34/72
  35. 35. Convention in Active Record Schema Conventions Column Name (Pattern) Use id (by default) Primary Key (singularized_table_name)_id Foreign Key 35/72
  36. 36. Convention in Active Record Schema Conventions - Optional Column Name (Pattern) Use created_at Timestamp updated_at Timestamp lock_version Optimistic Locking type Single Table Inheritance (association_name)_type Polymorphic Association (table_name)_count Cache the Number fo Belonging Objects on Associations 36/72
  37. 37. Convention in Active Record Using Timestamps ALTER TABLE products ADD COLUMN created_at datetime; ALTER TABLE products ADD COLUMN updated_at datetime; SQL created_at : 레코드가 최초 생성될 때 현재 날짜와 시간을 설정 updated_at : 레코드가 갱신될 때마다 현재 날짜와 시간을 설정 · · 37/72
  38. 38. Overriding the Naming Convention When Need to Follow a Different Naming Convention Rails Application with a Legacy Database · · 38/72
  39. 39. Overriding the Naming Convention Example CREATE TABLE `book` ( `book_id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, `description` text, PRIMARY KEY (`book_id`) ) SQL 39/72
  40. 40. Overriding the Naming Convention Set Custom Table Name class Book < ActiveRecord::Base self.table_name = "book" end RUBY use ActiveRecord::Base.table_name= method· 40/72
  41. 41. Overriding the Naming Convention Set Custom Primary Key class Book < ActiveRecord::Base self.table_name = "book" self.primary_key = "book_id" end RUBY use ActiveRecord::Base.primary_key= method· 41/72
  42. 42. Live Coding 42/72
  43. 43. Migration Definition 일관성 있고 쉬운 방식으로 데이터베이스를 변경할 수 있는 편리한 방법 · · · · 43/72
  44. 44. Migration Create New Model with Rails Command # rails generate model {ModelName} [{column_name}:{type} [...]] rails generate model User name:string TERMINAL invoke active_record create db/migrate/20150131045821_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml OUTPUT migrate 파일을 생성 (db/migrate 디렉터리) model 클래스를 생성 (app/model 디렉터리) 테스트 유닛을 생성 (test 디렉터리) schema.rb 파일을 최신으로 갱신 · · · · 44/72
  45. 45. Migration Migration File (crete_table) # in db/migrate/20150131045821_create_users.rb class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.string :name t.timestamps end end end RUBY 45/72
  46. 46. Migration Execute Migration rake db:migrate TERMINAL == 20150131045821 CreateUsers: migrating ====================================== -- create_table(:users) -> 0.0158s == 20150131045821 CreateUsers: migrated (0.0159s) ============================= OUTPUT rake db:migrate 현재까지 수행하지 않은 마이그레이션을 일괄 수행 rake db:rollback으로 마이그레이션 수행 취소 가능 schema_migrations 테이블 내에서 migration version을 관리 · · · · 46/72
  47. 47. Migration Generate Migration # rails generate migration {MigrationName} [{column_name}:{type} [...]] rails generate migration AddAgeAndJobToUsers age:integer job:string TERMINAL invoke active_record create db/migrate/20150131052039_add_age_and_job_to_users.rb OUTPUT migrate 파일을 생성 (db/migrate 디렉터리)· 47/72
  48. 48. Migration Migration Naming Convention source: Head First Rails 48/72
  49. 49. Migration Migration File # in db/migrate/20150131052039_add_age_and_job_to_users.rb class AddAgeAndJobToUsers < ActiveRecord::Migration def change add_column :users, :age, :integer add_column :users, :job, :string end end RUBY 49/72
  50. 50. Migration Execute Migration rake db:migrate TERMINAL == 20150131052039 AddAgeAndJobToUsers: migrating ============================== -- add_column(:users, :age, :integer) -> 0.0220s -- add_column(:users, :job, :string) -> 0.0168s == 20150131052039 AddAgeAndJobToUsers: migrated (0.0389s) ===================== OUTPUT 50/72
  51. 51. Migration Whenever you need to alter Database migrate를 만들고 rake db:migrate · · 51/72
  52. 52. 참 쉽죠? 52/72
  53. 53. 하나만 더 해 봅시다. 53/72
  54. 54. Migration Generate New Model with Relationship rails generate model TodoItem user:references title:string memo:text TERMINAL invoke active_record create db/migrate/20150131054248_create_todo_items.rb create app/models/todo_item.rb invoke test_unit create test/models/todo_item_test.rb create test/fixtures/todo_items.yml OUTPUT 54/72
  55. 55. Migration Execute Migration rake db:migrate TERMINAL == 20150131054248 CreateTodoItems: migrating ================================== -- create_table(:todo_items) -> 0.0444s == 20150131054248 CreateTodoItems: migrated (0.0445s) ========================= OUTPUT 55/72
  56. 56. Migration Modify Models # in app/model/todo_item.rb class TodoItem < ActiveRecord::Base belongs_to :user end RUBY # in app/model/user.rb class User < ActiveRecord::Base has_many :todo_items, dependent: :destroy end RUBY User 모델과 TodoItem 간에 1:다 관계를 맺고 User 모델이 삭제될 때, 연관된 TodoItem들도 삭제되도록 dependent를 지정 · · 56/72
  57. 57. Live Coding 57/72
  58. 58. Further Reading: Active Record Migrations 58/72
  59. 59. Validations What is Validations? 모델이 데이터베이스에 저장되기 전에 모델 상태의 유효성을 검증 · · 59/72
  60. 60. Validations Simple Example # in app/model/user.rb class User < ActiveRecord::Base validates :name, presence: true end RUBY User.create # => false User.create! # => ActiveRecord::Record Invalid: Validation failed: Name can't be blank RUBY create, save, update 등 저장 명령이 수행될 때 => 유효성 검증이 실패하면 false를 반환, 실제 데이터베이스에 저장되지 않음 Bang 메서드(create!, save!, update!)의 경우 => 보다 엄격한 검사를 수행: 실패시 ActiveRecord::RecordInvalid 예외를 일으킴 · · · · 60/72
  61. 61. Validations 언제 유효성을 검증하는가? method ! method create create! save save! update update! 61/72
  62. 62. Validations Skipping Validations (1) method decrement! decrement_counter increment! increment_counter toggle! touch increment! 62/72
  63. 63. Validations Skipping Validations (2) method update_all update_attribute update_column update_columns update_counters 63/72
  64. 64. Validations Skipping Validations (3) User.save(validate: false) RUBY save 메서드의 경우 validate: false와 함께 수행하면 검증 절차를 건너뜀 매우 유의하여 사용하여야 함 · · 64/72
  65. 65. Further Reading: Active Record Validations 65/72
  66. 66. Callbacks What is Callbacks? Active Record Object 생애 주기상의 특정 시점을 후킹 해당 상태의 시점에서 응용프로그램 혹은 객체의 데이터를 제어 · · 66/72
  67. 67. Callbacks Creating an Object Available Callbacks before_validation after_validation before_save around_save before_create around_create after_create after_save 67/72
  68. 68. Callbacks Updating an Object Available Callbacks before_validation after_validation before_save around_save before_update around_update after_update after_save 68/72
  69. 69. Callbacks Destroying an Object Available Callbacks before_destroy around_destroy after_destroy 69/72
  70. 70. Callbacks Sequence of Active Record Callbacks source: Active Record in Rails 4 70/72
  71. 71. Further Reading: Active Record Callbacks 71/72
  72. 72. <Thank You!> To Be Continued...

×