首页资源分类其它科学普及 > Ruby on Rails 4 Tutorial 中文版(原书第二版)

Ruby on Rails 4 Tutorial 中文版(原书第二版)

已有 456470个资源

下载专区

上传者其他资源

文档信息举报收藏

标    签: RubyonRails4Tutorial

分    享:

文档简介

Ruby on Rails 教程

Ruby on Rails Tutorial 中文版

文档预览

̴DŽ ü¥ kέЌέ ..................................................................................................................................................................................... iv ρ IJЙέ .................................................................................................................................................................................. v Ʈ.................................................................................................................................................................................................. vi ͩ 1 ͥ Mұ»ѸΧ...................................................................................................................................................................... 1 1.1 ͮK........................................................................................................................................................................... 2 1.2 Ɂƶ̒Ň................................................................................................................................................................... 6 1.3 ̛ git ‚̂ʄȸ¼ .................................................................................................................................................. 20 1.4 ѸΧ......................................................................................................................................................................... 30 1.5 ƄΔ......................................................................................................................................................................... 35 ͩ 2 ͥ ˲͈͘Ʈ........................................................................................................................................................................ 37 2.1 ϰ±͘Ʈ................................................................................................................................................................. 37 2.2 Users Ьˬusers resource................................................................................................................................ 40 2.3 Microposts Ьˬ...................................................................................................................................................... 52 2.4 ƄΔ......................................................................................................................................................................... 61 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ............................................................................................................................................................ 63 3.1 ҴǙҹҷ................................................................................................................................................................. 66 3.2 ͩ ˜Ѝ............................................................................................................................................................. 73 3.3 ɽ˸ÌǙŹ̫ҹҷ............................................................................................................................................. 81 3.4 ƄΔ......................................................................................................................................................................... 90 3.5 Ό1......................................................................................................................................................................... 91 3.6 ӑΈȎʅ................................................................................................................................................................. 93 ͩ 4 ͥ Rails ηĊ̫ Ruby ..................................................................................................................................................... 104 4.1 ƀϷ....................................................................................................................................................................... 104 4.2 Ūͨ"ěɟ˓....................................................................................................................................................... 108 4.3 ˜P̫ɕȰͶľ................................................................................................................................................... 114 4.4 Ruby Ͷ................................................................................................................................................................. 124 4.5 ƄΔ....................................................................................................................................................................... 132 4.6 Ό1....................................................................................................................................................................... 132 ͩ 5 ͥ ŰĦƞƎ...................................................................................................................................................................... 134 5.1 ˦Ê AΔʐ....................................................................................................................................................... 135 5.2 Sass ě asset pipeline............................................................................................................................................ 150 5.3 ƞƎ ̫҈ȷ....................................................................................................................................................... 159 5.4 ̛Ȁ˕ž ͩ ʷ............................................................................................................................................... 171 5.5 ƄΔ....................................................................................................................................................................... 175 5.6 Ό1....................................................................................................................................................................... 175 ͩ 6 ͥ ̛Ȁʬľ...................................................................................................................................................................... 179 6.1 User ʬľ .............................................................................................................................................................. 180 ii ̴DŽ 6.2 ̛ȀɕȰӎЈ....................................................................................................................................................... 189 6.3 Êů’ź̀....................................................................................................................................................... 203 6.4 ƄΔ....................................................................................................................................................................... 214 6.5 Ό1....................................................................................................................................................................... 214 ͩ 7 ͥ ̛Ȁ˕ž...................................................................................................................................................................... 216 7.1 ɯ̛͈ȀxǠ....................................................................................................................................................... 216 7.2 ˕žϥÞ............................................................................................................................................................... 232 7.3 ˕žŗХ............................................................................................................................................................... 244 7.4 ˕žǺÉ............................................................................................................................................................... 252 7.5 ƄΔ....................................................................................................................................................................... 259 7.6 Ό1....................................................................................................................................................................... 259 ͩ 8 ͥ ̨DŽěѠ¬.................................................................................................................................................................. 262 8.1 session ę̌DŽŗХ .............................................................................................................................................. 262 8.2 ̨DŽǺÉ............................................................................................................................................................... 277 8.3 Cucumber ͮKѥЙ..................................................................................................................................... 295 8.4 ƄΔ....................................................................................................................................................................... 302 8.5 Ό1....................................................................................................................................................................... 303 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ.............................................................................................................................................. 305 9.1 ɹɞ̛Ȁ............................................................................................................................................................... 305 9.2 ʈҤҤ¼............................................................................................................................................................... 315 9.3 ²¬ȁɽ̛Ȁ....................................................................................................................................................... 326 9.4 ·Ҧ̛Ȁ............................................................................................................................................................... 341 9.5 ƄΔ....................................................................................................................................................................... 349 9.6 Ό1....................................................................................................................................................................... 351 ͩ 10 ͥ ̛Ȁ̫ǎà................................................................................................................................................................ 355 10.1 Microposts ʬľ.................................................................................................................................................. 355 10.2 ɯ͈ǎà............................................................................................................................................................. 368 10.3 ǎà̷–̫Ɉk................................................................................................................................................. 377 10.4 ƄΔ..................................................................................................................................................................... 399 10.5 Ό1..................................................................................................................................................................... 399 ͩ 11 ͥ –˕̛Ȁ.................................................................................................................................................................... 403 11.1 –΀ʬľ............................................................................................................................................................. 403 11.2 –˕̛ȀÉι̫Τҹ̠ҷ................................................................................................................................. 419 11.3 ÌǙ²ϥ............................................................................................................................................................. 443 11.4 ƄΔ..................................................................................................................................................................... 450 11.5 Ό1..................................................................................................................................................................... 453 iii kέЌέ ,ĤĿĤ ʄ2̫ύɘ̂êkέɮ Michael Hartlȏ Ruby on Rails Web ƷòKΑΖG̫ϡέP*ÀɺΒ¢kƫƷò5 RailsSoace ʄNjѐɩ̫ Rails ɓ͘ 0ɺn̛ Ruby on Rails Ʒòѐ ĉ$ Insoshi ̫͉BΤΗƩÿїƩÿ ɺΒNj˚ϡ̓ĴƝΒѐ˄5ĭ$Pž Ruby ͉×̫У̏: 2011 ƪϧȲ65 Ruby Hero ŜPˁ:ĝjŭ ҥƫϓnj5ÊƗ̕Ƙŭҥ̫̄̕ŭàʼnŭdPіɮ Y Combinator µέһ̴̫ˁ̚ ʄ2̫ ɘ̂Ќέɮ Andor ChenPˁ: ßœŭ̓Ĵ ŸIJӁ̫ҋ͎ũ̞ˉ¼ѭ[XβʆʧƘ͘Ơ ̛ѐ WordPress ̫ЙέǼЄ_˾ǣїĉŪ̓ĴPɮ Ruby ¶ŭέƫĴŭ1n̛ Rails ‚ Web Ʒòʄ2Ɗ ɮPĴŭ1 Rails ̫ѐ͘ ΪЌ̫ iv ρ IJЙέ ĪmŅĤ Ruby ɮ ҒNjΨ̫ϹͯʆДϷ˜ІϹê³Ɗɮ“ϽΠ͘GĕǕ-”David Heinemeier Hansson Ɗɮ̺ѿ5ї ˸ȃĴƷò Rails ʤʖɩѥȟ5 RubyRails Ƥϧ͖k Ruby on RailsŮϽ Web ƷòõnjMʂї(ǕѬ0Mʂ ŠʶͮÞĴѐë̫©ƪ Ruby on Rails Tutorialїʄ2ϧϱ$KΑn̛ Rails јϡ Web Ʒò̫ӌέ Ĵї’̔=γ̫̠ ϹͯʆΠ͘ě Web ư̛͘ƮƷòѹĴя̍òƒǻNjʁNJι$ IJ̫Ʒòέȼp Ruby on Rails łϾŭ1ύДїҒ̠ДϷɮNjѿϬ̫cѫѐʾДŭ1LjLj_ɹɽɐʔʵĭ$їʠǃ̺» Andor Chen ȏRuby on Rails TutorialΪЌǺ ɘɩǻNjӑ— ǻMʂ»ѐ IJc Ų_Ĵʂʌ̫ʗ ŔѭЇơʀǻ» IJɩιϮ»ʄ2̫ AЙέ ϦǏ̫͍͊lU Ruby on Rails Tutorialkέ Michael Hartl êɘ Ruby is a delightful computer language explicitly designed to make programmers happy. This philosophy influenced David Heinemeier Hansson to pick Ruby when implementing the Rails web framework. Ruby on Rails, as it’s often called, makes building custom web applications faster and easier than ever before. In the past few years, the Ruby on Rails Tutorial has become the leading introduction to web development with Rails. In our interconnected world, computer programming and web application development are rapidly rising in importance, and I am excited to support Ruby on Rails in China. Although it is important to learn English, which is the international language of programming, it’s often helpful at first to learn in your native language. It is for this reason that I am grateful to Andor Chen for producing the Chinese-language edition of the Ruby on Rails Tutorial book. I’ve never been to China, but I definitely plan to visit some day. I hope I’ll have the chance to meet some of you when I do! Best wishes and good luck, Michael Hartl Author The Ruby on Rails Tutorial v Ʈ › ǻ*ÀƘk̫“ăCD BabyɮœƽɢӚ̫т̛ Ruby on Rails ɼɨ̫[* ˼ĊíɹÊǰ̼̫ȮĬ5 PHPþTĴ Google ȿ΂ǻ̫ĉŪιȿ»–:їĶҗÂ̫ɘͥNjŐGѹǁ˺ȹϐ Michael Hartl ̫їʄ2 ȁTǻnjЙ ЙŰRuby on Rails TutorialĊǻíю͗» Rails ‚Ʒò5 ǻЙѐNjŐ Rails ̷–̫2cɮїʄ̻ʵϽǻ‘Ғ52Ѿ̫ °ѹNjͨć“Rails *ѱ”ǻTÀϳnjїѱNj ο˼cɮЙŰїʄ2dzϳæɮο˼ɣˀʄ20ɮġ ʄοţπΐѹɮ̛˜ЍӌÌƷò̕ǖ̫ Rails 2͵ NjŐϡŸѹȹϐn̛ TDDcɮĴʄ2¬̂*ÀMˎɽϧŠʶ˧ʪ̫KΑѐ2 ̫͈oі̛»5 GitGitHub ě Herokukέ̻̫ɮϽlgӎ5 ȏƷò̻ʵι̛̫͘ƮɮH(dzϳή2 ̛»̫R̀ƫɮ«͝Ȫѭ̫ ΋ǝöѝɮNjş̫ʬƻǻϊ5ɗŔ̫ɩҖҘЙ5ʄ2‚52 ȁɽ̫͈o͘ƮěΌ1MŘπƍǍƮ˨ јϬн̽Йїʠȃιї͑M ɋ̮ Dô Rails ̫̲ŷĎ Derek Sivers (sivers.org) CD Baby µţG vi ͩ 1 ͥ Mұ»ѸΧ ĉ 1 ć !ůHŞĢ ʮђŭ1Ruby on Rails ɓ͘ʄ2̴̫ʜɮǺ$ž“Šʔǯŭ1n̛ Ruby on Rails јϡ Web ƷòǻưВMĠ ‰Ʒţ ”ї ҕӄ̫ɼşͫʥŭ1Űʄ2̫Ź*Ċlƃ™ōn̛ Rails јϡƷòěѸΧ Web ͘Ʈ̫ȎιĈ ɩlіιŒѫѐ AјҜ̫2͵àŴěϱӃɓͪ͘˘и̫ Rails ɓŭg΀ΚΛˤѭʄ2Ń: Rails 4їѾ̫̾ ЉRϥ̽ Web Ʒò̫òƒɟċRuby on Rails ɓ̫͘ɼɞ̂ʄþTMʄ2̫Τͤϓó l̓Ĵ̺»̫ɮ҂ž Rails 4 ̫̂ʄȁɽŹѹě Rails 4 ›Źcїƫɮ ɞ̂ʄĭ$ Rails 4 ̫õÔі ˎœ»ɞ¬ ̂k$ ʄ‘Ғ2ʄ2ě*À҂ž Rails 3.2 ̫̂ʄƛºNjƄƄõÔϝŐГϮɡ˕ 1.1c %Ϭ̫õÔɮ ͖$“„Ŋìɕ”̫ɞů’Ȏʅ_Ĵ 7.3.2 ω KΑüϬ Rails ̫õÔзœǻƊ_ɞ¬ ̂ KΑ Turbolinks ěuΥɝŝŦΟūͪȎʅі_KΑ RSpec ̫ɞ̛˓oŠ“Éι˜Ѝ” Íå 1.1 ĉïû” ҷ̫²ϥ²¬5ʄ2ěͩ9̂*Җ©+ȁɽ̫ƛƸɼѿϬ̫ ƛƸɮn̛5“„Ŋìɕ”˜Pѹɮ ƄõÌǻ²¬ї²ϥɮ$5ɟtͩ9̫̂ЙέǼέ˾ǣ Rails 3.2 ̫ЙέǕѬʙ̺̫̂Ĉ*Ō Šʔlˎ̛ѐ Rails 3.2 ИỤ̈́ї²ϥ ²ϥ̫ʿ һĊҷѹɽ ҈ȷȦċõÌȁĴ̫ͥωǼR̀ • M Rails 3.2 ÛΈ» Rails 4.01.2.2 ω • ɯƻƼ‘ Capybara DSLR̀ 3.10 • ȏ RSpec ̫ .should ú˓ȮǺ5 expect().to3.2.1 ω • ȏ have_selector('title', ...) ȮǺ5 have_title(...)3.3.1 ω • ɹɞɈkȁ̛̫ HTTP ИˇM PUT ȮǺ5 PATCHɡ˕ 3.3 • Ƽ‘ʠƻϥě JavaScript μʄɩȦŲ5҂ž Turbolinks ̫ìɕR̀ 3.26 • ȏ root to: 'path' ȮǺ5 root 'path'R̀ 5.24 • ȏ find_by_thing(...) ȮǺ5 find_by(thing: ...)6.1.4 ω • ȏ rake db:test:prepare ĚSȮǺ5 rake test:prepare6.2.1 ω • Ʌȳ attr_accessibleƠ̇“„Ŋìɕ”7.3.2 ω • Ơ̇Êź̫ЁǑʈʜ8.2.1 ω • ȏ before_filter ȮǺ5 before_actionR̀ 9.21 • n̛ Capybara ̫ match: :first ìɕ˸­ͩ ÖѺ̫҈ȷR̀ 9.43 • ȏ default_scope ̫ìɕM Hash ȮǺ5 lambdaR̀ 10.11 • ȏ dup ȮǺ5 to_a ɟ˓R̀ 10.12 • n̛ XPath ˜Ѝȧ̫҄̉ǙõÔ11.2.4 ω ˕DZʄ2̴̫ʜƫIIɮɓl Railsήɮɓlǚʠn̛ Rails јϡ Web Ʒòɓ_l$ĭ̆ΤƷòфV̫Ȏ ιҦ5Ђ» Ruby on Rails *ŏˠî»̫Ȏʅіɽ HTMLCSSɕȰƯ̂ʄȸ¼˜ЍěѸΧ$5эǺŭ 1 1̴ʜʄ2n̛5 Űɗ̫ɟʥ ѫѐųoŭ1n̛ Rails MұƷţµƶ ̻ʵ̫͘ƮŠ Derek Sivers ĴÀ Ϸ ȁЗ̫ʄ2ŹѼ̛΋ǝTDDΔʐҲϬMŘƷţȧҼƮЙ»ΔƍŠʔlΒƤн̽ҘЙȎʅͶ2͵ї͑ ΋ǝ̫΍ΏɟƻҲϬlѢư lþTƃʄ2Іǯ$ ̞ũ˫ǹŭ1Űʿ ͥƊ_Û ΈήΌ1Ɗɮʿ –̫ƄǞœ ʄͥӊƃKΑŠhůϪ Ruby on Rails ȁҲ̫фVɁƶƷòȁҲ̫̒Ň1.2 ω˼Ċµƶͩ  Rails ͘Ʈ first_appʄ2_ѴM A^͏̫фVƷò1ǭȁTĴµƶͩ ͘ƮĊǻU_͢åƃŮɎ»̂ʄȸ¼΀Ι Git 1.3 ωɼĊǻUіƃȏї͘ƮɎ»ųҠ̫̚C̒Ň ѓϡ1.4 ω ͩ 2 ͥǻU_µƶͩ9͘Ʈ˲͈ A Rails ͘Ʈ̫ŃʄɈk$5ǕѬµƶǻU_n̛μȂʖÉιɡ˕ 1.1ʌµƶ ͈o͘Ʈĉ$ demo_appĭ$̚Ǻ̫R̀іNj͸;0NjŎʇͩ 2 ͥƃү ͻÇĴѫѐ˝ϲ ĩ̫ URI ΒƤ͖$ URL1ʌě͘ƮB=ї ˸ ʄ2Ã̫ͥωƃKΑMұƷţƷò œľ͈o͘Ʈĉ$ sample_appĴї͘Ʈ̫Ʒòѐ͘ ƃn̛ “˜ЍӌÌƷò”Test-driven Development, TDD̕ǖMͩ 3 ͥƷţµƶҴǙҹҷ˼ĊňÊ AÌǙ̫Ź ͩīͥ³_ͮϬ̫KΑ  Rails ηĊ̫ Ruby ͘ƮДϷͩ>ͥ»ͩ/ͥƃѧʷŰĦї͘Ʈ̫Ń̈́ʤʖ Τ̫ͤ ƞƎ̛ȀɕȰʬľŰɗ̫˕žěӎЈ΀ΙɼĊĴͩ 10 ͥěͩ 11 ͥƃ˦Êǎàě͉BÉιɼΐƷò¬  þTųҠѓϡ̫͈oΤͤ ɼΐ̫͈o͘ƮƃĴŏϥě ĈʠѼ̛ Rails Ʒò̫ǎàΤͤÙ¯̷b2ϝ˼ǻUƃ%Ϭ̫ͻÇү Ĵї͈ o͘Ʈ5cɮʄ2̫ѿ˸æĴ:ȼp Aѫ̛̫ɟ˓їʠlƊ_™ɽļų̫ŃʄÉЅƷòH(ʠ̫ Web ͘ƮѹιŒ˙̛Ķ 1.1 Č ο 2004 ƪ¬̓TʌRails яѬǺ$ÌǙ Web ͘ƮƷòӁŁÉιɼǁœɼôʮђ̫ʤʖ* M¶µ̫һ̴»Nj Ő̫œ“ăѹĴn̛ Rails 37signalsGithubShopifyScribdTwitterDisneyHulu ě Yellow Pages ͪї ²ϥіNjґɽNjŐ Web ƷòƘkŵ0Ĵn̛ RailsˀŠ ENTPthoughtbotPivotal Labs ě HashrocketTîɣ ɕ̫̌͢ҾҕłϾGĕěһ̴ȍÓĢ ɮH(nnj Rails ŠʶǺÉĖ ӊRuby on Rails ɮےƷˬ̫Ń: MIT ÝϿòƞþTЫцn̛ Rails ̫ǺÉɽNjœ Ѹ¯ɮnj̮:Ů^Үή΃¨̫ІϹ́1 Ruby ДϷ̫ӑþȇƒǝĊRails Ʒò5 ŝ̛:Ʒ ò Web ͘Ʈ̫“ӁŁƓДϷ”Domain-speific Language, DSLȁT Web Π͘ ˆ̚Ǻ HTMLµƶɕȰʬ ľURL м̜ͪXËĴ Rails ѹNjŹɫų̓ɼΐnj»̫͘ƮR̀Njͮ˖ήþЙǝчӑ Rails і_ǕѬкј Web ӁŁɼɞ̫ȎʅěʤʖʖʐȎʅoŠRails ɮɼɨų̓ REST ї Web ͘Ʈʖʐg΀̫ ʤʖ* ї g΀ƃЩ͞ʄ2ǃ˜P̫ʤʖƷò¬ǺÉ̫ɞȎʅĊRails ̫µƶέ DHH î˜ʡǏƷòĮҙ _˃̊Р̫ƃ˜ĒΊјʌǼЄɼšľ̫oũƊɮ Rails ě Merb ě Rails Ͷb̫ Ruby Web ʤʖһ̴̫ ćƫїʠ ʌ Rails ƊΚȍ5 Merb ̫ʬĻÔІϹ͚Ų̫ APIǝι0nj»5ȼÛ 1. URI ɮΙ ЬˬʜЉͨUniform Resources Identifier̫͖ͮчƅn̛̫ URL ɮΙ ЬˬŲdͨUniform Resource Locator̫͖ͮĴųҠn̛ URL υě˝ϲĩĵĸʞ ̫Ź ʠ 2. Ќέ˕ Ȧ Twiiter 2 ͩ 1 ͥ Mұ»ѸΧ ɼĊ ˸Rails ɽ ˘иήՋÔ̫͉×͉× ɽɕT̪Ϲ̫Ʒˬһ̴У̏έ΍Ώ5NjŐ_ϿƷò5œҀ ̫ gemіɽNj՝Ź!Ż̫àŴ AϼЅ΍ě IRC ӃѱɽŠʶŐɕҀ̫ Rails ͘Ʈĕ0nnjŌ̕͘ƮҌЕõ njͮÞ5 “n̛ Google ȿ΂ҌЕxǠ”̫ɟ˓©+ǟιȿ» ͳ̷–̫àŴɘͥǼϼЅ΍̫Џӄ 1.1.1 ę aŅĤģûžĺ ʄ2̫ŹIüɮЂϵ Railsі_ˠî Ruby ДϷRSpec ˜ЍʤʖHTMLCSSƅҀ̫ JavaScript ě A SQLȁTͰl̫ Web ƷòȎιŌĴH(ƏʭЙŰʄ2ĊlƊιŒΚΛŭ1 Aч$ӑΈ̫ Rails Ьˬ5Ĉ ɩ0_ž2 ȼ»̫˜PȎʅɽ œg̫ϻЉї(З0DZĘ̽ʄ2Ϭϭ̱NjŐ̾ЉŠʔlɮ ɽAΒӎ ̫͘Ʈĕŭгʌ_ϳnjɽAąÇҷƊʢȰĈ̫ƷòηɲΖ¬n̛ʄ2̫ AƶϿ Íå 1.2Ĩ°ÙѨÑČRÑŃ Rails ¬̓\ţƊĒƼ5]Ő̴Ž̆ºɮ Rails µţG DHH David Heinemeier Hansson¼k̫ϖĉ̫“15¯ ҃àŴ͘Ʈ”ϱӃВϱӃTî˜Ϣ̂̚ʄɮ͡ȶ Rails ǁœÉι ͑Njş̫ɟƻǻȹϐl0̺ їAϱ ӃÂѦ  їAϱӃ ̫˲͈ιȸ¼Ĵ15¯҃nj̮: ý‚“μȂʖscaffold”̫ÉιŮѫѐ Rails ĚS generate ̚CœҀ̫R̀ NjŐG¼k Rails ɓ͘ɩѥȟn̛μȂʖÉιĭ$ŮɹǕɹͮÞɹЖGѐμȂʖ_̚ǺœҀŎʇ̫ R̀_n¶ŭέC̚įǩϝ˼_̛5cæɪ̩»Ʊò̚5H(8n̛μȂʖÉιþι_ȏlõǺ  μʄ̚Ǻĩ̫n̛έcæ_ňјlž Rails ̾Љ̫ȴȾ ʄ2ƃѼ̛ ͑Ĉ̫ɟƻϝ˼ͩ9ͥ_̛μȂʖƷò Ƅľ̫͈o͘Ʈcʄ2̫ʡǏɮMͩͥƷţ Ʒò̫ч$œľ̫͘ƮĴƷòїœľ͘Ʈ̫ʿ ҜʼǻUü_Π¢ƅҀ̫R̀ɫ:̕ϵcí™ɽ Ų ̫Ȩǽǝїʠ̫ѐ͘ɼΐ_Ͻlž Rails ̾Љɽч$ˤ¾ĵ̕ϵι˶˘ѓ̛µƶ©+XhͶľ̫ Web ͘ Ʈ ȁɽЙέ ŭ1 Rails ɩ ƤϮ̫̥ҕɮɮčϬŭ1 Rubyїҕӄ̫ͫʥó¤:lG̫ŭ1ɟƻTîl ȁ™ɽ̫Π͘ΒӎŠʔlơʀч$΀Ι̫LJƱŭ1ǼέlTÀMʂΠ͘ѐѶ(ŭ Ruby ǼЄɹѢćlǻ ȹϐlҘЙ Peter Cooper ̫Ruby ‘Ғ 2NjŐ Rails Ʒò¶ŭέNjǯ͢ӋƊƷţ Web ͘ƮƷòήɮĴʶ *ÀҘЙ ʄ 500 ŐҹΉͺЂϵ Ruby ̫2ŠʔlɮїͶGΩǻȹϐlĴ Try Ruby ŭ1 A̿Ƅ̫B=ƻɓ ͘˼ĊіþT̺  Rails for Zombies їЫ̫ϱӃɓ̺̺͘ Rails ѹι‚AH( ûŏ ƤϮ̫̥ҕɮɮčϬĴ ƷţƊn̛˜ЍƊŠÀҷ̫KΑȁЗ̫ʄ2_n̛“˜ЍӌÌƷò0ý “˜ЍĊƷò””̕ǖǻϻ$їɮn̛ Rails јϡ Web Ʒòɼş̫ɟƻcїʠ0_ňÊҭƴěŎʇƴŠʔl ϳnj‚˜ЍɽAįҭǻƶϿlĴͩ ѰҘЙɩ̶ȷнѐȁɽ˜ЍǼέɹş̫ɮüȏŮUǃ‚ӎЈR̀ʵ͆ ǝ̫Ƙ™ή̛Ͱ˜Ѝ̫ʆ̕ŠʔѼ̛Ċ ͑ɟ˓lϬµƶ AǐϬ̫˜ЍɘVý‚ spec˼Ċƃʄ2 ȼp̫˜ЍR̀Π¢јë˼ĊѓϡїA˜Ѝ̛oͩ>ͥ_KΑnj»ŗХ˟Ǡ˼ĊΠ¢R̀Ÿѓϡ˜ЍϽ ˜ѫѐ Σ,Βӎ̫͘Ʈĕ ʄ2̫%ϬЙέΩɮ´‘Ғ̫͘ƮĕWeb ͘Ʈî˜̷–̫XDZ ȎʅѹɮNjŎʇ̫Š ʔlےɮ Web Π͘ϔӔò̓ʄ2̫Źŕҭ5ǻƶϿlŭ1Ńʄ̫ HTML ě CSSNjþǪї͑Ȏʅ ǻˎɽȹϐ̫2͵cɮˤ‘˛¬ HTMLưВҌ Йέȹϐ David Sawyer McFarland ̫CSS ųǽȂ 3 ž˼ĊŸЍ̽ҘЙʄ2l0þTάϛҘЙ Peter Cooper ̫Ruby ‘Ғ̫À©ͥї©ͥ ̫͈o͘Ʈ ѹˀÉιŰĦ̫ Web ͘ƮƄnjŐѐ0ɽ ȋ¶ŭέѫѐʄ2ŭ_5 Web ƷòȁTlŢ0Ѝ ήǻ ǁ˺ȹϐʄ2Ѻŝ̫ɓŭϱӃѫѐϯ̺ºG̫Ɉkʌŭ1 Rails Ʒò Βӎ!Ż̫͘Ʈĕcɮ´ȷ϶ Web Ʒò TÀ̫ΒӎЗɪlþιƝΒ̕ϵ5Ͷɟ˓ɕȰΔʐͪʫǖїɮ ş̫ƷţѐŠʔlTÀɮ C/C++ Ǽ Java ͘Ʈĕl_ϳnj Ruby ɽ˸ûͶҲϬϊ ʼɩҖȃιѢư Ƕ Ƕ̫Ѣưl_1ǭ̫ŠʔlųĴɣ˓Ɏƹn̛ϡƍ̫¯ĂRuby ŠЄlї(‚ʄ2_$lKΑȁɽ Web ̷–̫ʫǖȁTŠʔl̓Ĵƫ̾ѱ POST ě PATCH ̫׺0Ϭ΃ Βӎ!Ż̫ Web Ʒòέcɮ´ȷ϶ Rails lɽNjş̫Ń̈́5ŠʔlɺΒn̛ѐ PHP Ǽ PythonɹşїAÌ ǙДϷƊɹş5ǻUϬЂ̫Ń̈́ѹɮ ρ̫cɮlþιž TDD іɽ Rails Ѽ̛̫ REST ʖʐdz»Ң̚ή Ruby ДϷɽοƜ̫ӈʣї ˸žlʌЗ0ɮҢ̫̚ Βӎ!Ż̫ Ruby ͘Ʈĕ ŠJ Ruby ͘ƮĕǷ Rails ̫NjƅŠʔlɮї͑ǧ¥þTǕѬ̫ѐ Ѱʄ2˼Ċ οƜÌȂƷò ư̛͘Ʈ Σ,Βӎ̫ Rails ͘Ʈĕ lǼЄҘЙѐ˜P̫ Rails ɓ͘0ƷòѐƄľ̫ Rails ͘ƮʢȰ AЙέ̫ñӉʄ 2іɮ_ΖlƢʌƣͺ̫ЗÞƊɩɐǝήϷʄ2_ˀlǃ¶ŭ1 Rails n̛̫ɓ͘Ϭɹɞ A Βӎ!Ż̫ Rails ͘Ʈĕ lҲϬҘЙʄ25cɮNjŐΒӎ!Ż̫ Rails ƷòέіɮЗPUMʄ2 ŭ»5Nj ŐǼЄѫѐʄ2l_Ȯϴƴʌ̺ Rails ЙŰʄ2ĊǻƶϿΒӎ!Ż̫͘ƮĕΚΛҘЙ David A. Black ̫The Well-Grounded RubyistRuss Olsen ̫ Eloquent RubyǼέ Hal Fulton ̫Ruby *ѱїʄ0ɮјҜ2͵ѐɹ$˕ʗĂŲ̫Џӄ ͰlɮMĠѾƷţ̫ŭŰʄ2lіưВΚΛŭ1 A ӑΈ Rails ЬˬTɮǻȹϐ̫ŭ1Ьˬ3 • RailsCastsRyan Bates ^͏̫ЫœŐɕϱӃɓ͘ • PeepCode ^͏̫ɋЫϱӃɓ͘ • Code School B=ƻ̫Π͘К͘ • Rails űɟȦß ȧЏӄΠ¢ΒƤɹɞ̫ Rails ìά • Ryan Bates ̫ RailsCasts ǻɮɮƝΒЗѐ RailsCasts5 ̻̫ǁ˺ȹϐ RailsCasts 1.1.2 Rails ûªħ ĴΚΛKΑ*Àǻǯϊ˸ɩҖЗɪ  Rails ʤʖòƞ¶ʁ ōôȦФ̫ҕӄ Rails ̫ǝιNjşoŠι Ō̕чœ̫ЇҕҀїҕӄ*ȁTūĴɮĭ$ɽAGˎɀ˧̉¥ǝιɮϬĴl̫Τͤ ^ÔήɮĴʤʖ ǁœ̫ Rails üɮ ʤʖήƝȁTҷ̫ҕӄưВȮϴƴʌ̺ n̛ Rails Ʒò̫ΤͤþT‚ǝι^Ô Č їʠ̫ҕӄƝΒnj»5ζŲ̫Ĭͫĭ$NjŐ̠ЇҕҀɼœ̫ΤͤƊɮ̛ Rails Ʒò̫ųҠǝι^Ô ˠî»̫IIɮ RailsŠʔl̫͘ƮҲϬŌ̕Ͷb Hulu Ǽ Yellow Pages ї͑ɕҀΈ̫ЇҕҀRails ƫ_Ȝl ̫Ċξ 3. Ќέ˕ Ruby ɘ͉×0ɽ AЧҀˀчӑ̫ЬˬŠ RailsCasts ChinaHappycasts ͪ 4 ͩ 1 ͥ Mұ»ѸΧ 1.1.3 Ó¹ïĔ† ʄ2 n̛̫ȵ̂·ŲNjŐѹɮϷοɪ̫ĴʄωǻϬЗ ѶADZ)ɮNj˧ɳ̫Ѹ¯ ʄ2̫ HTML ̂ě PDF ̂ѹÓď5œҀ̫҈ȷɽѸĆͥω*Җ̫҈ȷoŠ 1.2ω0ɽ҈ȷ»˜PΤ̫ͤ ҈ȷoŠRuby on Rails цҹҷ4 ʄ2 NjŐoũѹ̛»5ĚSϡĚS$5ϡɘɟtȁɽ̫ĚSϡ͈oѹn̛5 Unix ӈʣ̫ĚSϡȼ͈ͨΨ ‹ͨĂoŠ $ echo "hello, world" hello, world Windows ̛ȀϬ̾ѱĴ Windows ĚSϡ̫ȼ͈ͨɮ > C:\Sites> echo "hello, world" hello, world Ĵ Unix ΀Ι  AĚSϬn̛ sudoдΈ̛Ȁ̫Ƙk“substitute user do”Ȇϡ5әϻǧ¥n̛ sudo Ȇ ϡ̫ĚSɮTͰ̕ĕ̫сYȆϡ̫їʠƊιЇҕɱѫ̛Ȁɣ˓Їҕ̫ɘVěɘVř5oŠ 1.2.2 ω ̫ o ũ sudo ruby setup.rb ĴŐɕ̫ Unix/Linux/OS X ΀Ι әϻҲϬn̛ sudocɮŠʔn̛ҷKΑ̫ Ruby ̂ʄͰ̕Ƙ™ƊˎǐϬn̛ 5̶ȷn̛TĚSåþ ruby setup.rb Rails ҟƢ5NjŐþTĴĚSϡ ѓϡ̫ĚSoŠĴ 1.2.5 ω ƃn̛ҷ̫ĚSĴʄĵѓϡ ƷòɿËĩ $ rails server ěĚSȼ͈ͨ ʠʄ20n̛5 Unix ӈʣɘVř¯ҫͨoŠ ɚ΋ /oŠǻ̫͈o͘ƮūɎĴ /Users/mhartl/rails_projects/sample_app Ĵ Windows ͪW̫ɘVřþιɮ 4. ҘЙʄ2ɩl_ò̓Ѹͥω*Җ̫҈ȷNjɽ̛lþTʙ̺Ƽ̛̫Ź˼ĊǕѬ̫Ĭ»*À̫dΦĴ˝ϲĩ ҘЙɩї͑ ɈkNjͮÞ̶ȷ˸­˝ϲĩ̫ĊѠȧ҄ƊþT5ѐ Adobe Reader ě OS X ̫Ӏϲ͘Ʈ0$ PDF ȼp5ї͑ÉιĴ Reader Ĵɘʦ ˸­ӛʜāҎ˼Ċѥȟ“ ϱij”ƊþTѕĬ5ĴӀϲ͘Ʈ Ϭn̛“˝ϲGo”ϔÞ ˝ϲ->ѕĬ Back 5. NjŐGѹҌЕĵϻ$ sudo ̫’͖ɮ“superuser do”ĭ$ŮƝдΈ̛Ȁroot̫сYȆϡĚS˜ųsudo Δć5 su ĚS ěύДÞЋ“do”ή su ̫’͖ɮ“substitute user”xlþTȆϡ man su ĚSӎЈ  5 C:\Sites\sample_app ͘Ʈ̫ʢ̴DŽ͖$“Rails ʢ̴DŽ”cɮї͖ęNjŹɫϽ AGC̚įǩPUT$“Rails ʢ̴DŽ”ɮȦ Rails ʤʖ̫ʢ̴DŽ$5ѵʹ)ʄ2ƃn̛“͘Ʈʢ̴DŽ”ɻR“Rails ʢ̴DŽ”̫͖ę͘Ʈ ȁɽɘVřѹɮ̷žВ ̴DŽ̫oŠ͈o͘Ʈ̫ config ̴DŽɮ /Users/mhartl/rails_projects/sample_app/config ї͘Ʈ̫ʢ̴DŽƊɮ config *À̫Ѹ¯ /Users/mhartl/rails_projects/sample_app $5ɟtŠʔҲϬȦċҷїɘV /Users/mhartl/rails_projects/sample_app/config/routes.rb ǻ_̹̣Àҷ̫͘Ʈʢ̴DŽ̶ȷ¢Ǻ config/routes.rb ʄ2ΒƤҲϬɯ͈ Aʌο˜P͘ƮĚSϡ̂ʄȸ¼΀ΙRuby ͘Ʈ̫ͪъ¬ĭ$΀Ι*ҖūĴƛƸl ȁnj»̫ъ¬Δʔþιěʄ2 ̫ĈcɮɣҲȘǏ lĴn̛ʗAĚSɩþι_ƀρ AҌЕ̫ò̚ǻ_ ²&ĆҌЕ̫ϵ¤ɟ˓lþTοϡѫѐ Google ȿ ΂ϵ¤ŠʔlĴŭ1ʄ2̫ѐ͘ ѯ»5ҕӄǻƶϿl̺ ʄ2ƣÍҹҷ ²¬̫Ьˬ 1.2 Àžòv ǻϻ$ͩ ͥƊˆ˓ŭҥ̫“ˢˊҜʼ” ʠŠʔlιǺÉ̫ɁƶƷò̒ŇĊҷƊ_NjҼ¹ – ʄ2Йέ Bob Cavezza ̓ĴþTƷţɁƶ Ruby on Rails Ʒò̒Ňƫµƶͩ ͘Ʈ5ʄω̫̾ЉҀˀчœ̆ºɮž:ˎɽNjŐΠ͘Β ӎ̫GʌЗȁTŠʔĴʗĵɟâf50Ϭ˵Ǐül GŠʶʿƷòέѹɮMї ʷбѐʌ̫Ƕ ǶʌÉŖТɽǏG 1.2.1 ŸYòv Ĉ̫GɽĈ̫ħşʿ Rails ͘Ʈĕѹɽ ŝοƜ̫Ʒò̒ŇcŃʄ¯$Ͷ ɘʄΠщĩ+ĚSϡ̫̒ Ňě“үǺƷò̒Ň”IDE=Integrated Development EnvironmentʌЗЗĊ ͑ IDE n̛ɼŐ̫ Rails IDE ɮ RadRails ě RubyMineǻĐЗ RubyMine Ҍ ЙέDavid LoefflerіǟΔ5 ͳ ɘͥЂϵŠhΔćʄ2n̛ RubyMineŠʔl1ǭn̛ IDEǻƶϿlȏҷȼ»̫©’ѹЍ Ȍ»ɼͨć οƜϬˇ̫ ʲ 6 ͩ 1 ͥ Mұ»ѸΧ ij 1.1 ɘʄΠщĩěĚSϡ̫Ʒò̒Ň ÉÓĞŏkhg%ĭ ч* IDEǻɹħʮn̛ɘʄΠщĩΠщɘʄn̛ĚSϡȆϡĚSŠij 1.1Šh΍ćó¤:l̫ħşěȁ̛ ̫Ʃÿ • ɘʄΠщĩ ǻȹϐn̛ Sublime Text 2їɮ лƩÿɊȥ̫ɘʄΠщĩͮÞɫŭÉιǁœ6 Sublime Text ˤô Textmate ̫džĞŮι›ŹœŐɕ Textmate ̫Ų¼ÉιoŠR̀́ʼěѺχɟʥ Textmate üþĴ OS X n̛Šʔln̛ Mac ̫ЏŮL˼ɮ Njş̫ѥȟûŏ Njş̫ѥ ȟɮ Vim 7Ůɽ҂žĆ͑%ϬƩÿ̫̂ʄSublime Text ҲϬQЫή Vim ³ɮЫ̫9έѹɮ̠ GʼnɱѰn̛̫ΠщĩcƊǻ̫ΒӎήϷSublime Text ž¶ŭέɹïş • ΐͦĚSϡ OS X ΀Ι ǻȹϐn̛ iTerm ǼɮΦ̫ΐͦ͘ƮLinux ΀Ιәϻ̫ΐͦƊNjşĴ Windows NjƠ̋ȀѥȟĴϜȝʆ ѓϡ Linux ʌƷò Rails ͘ƮѶ(ΐͦƊn̛әϻ̫ş5Šʔ lɮĴΉ Windows ΀Ι Ʒòǻȹϐn̛ Rails Installer ҟƢ̫ΐͦ Šʔl¤Ųn̛ Sublime TextþTì˽҂žʄ2̫ůϪЗɪʌůϪїAІΦþιɽA΅̖ɫ:¬Ҍȁ TǻüȹϐΖӑΈ̛Ȁn̛åt‚їAІΦSublime Text 0ɮΠ¢ Rails ư̛͘Ʈ̫ΘmƘ™ çĴk ϝ˼˝ϲĩɽNjŐѥȟcɮœŐɕ̫ Rails Ʒòέn̛ FirefoxSafari Ǽ Chrome јϡƷòї˝ϲĩѹƶ 5“ʙ̺‹΁Éι”Ĵҹҷ āҎ˸­ǼÊ Control ҎþTЛ¬ 6. ¢kʄ2ɩSublime Text 3 ƝΒȹ¬5 Beta ̂cüž Sublime Text 2 ̫˕ž̛ȀƷɎǻüƶϿƉӓ̛ȀÛΈ 7. vi Πщĩɮ Unix ùΫήǁœ̫ǁÇƘ™Vim ɮ vi ̫ňǁ̂vi improved 7 :’<ûîńÏ ĴɁƶƷò̒Ň̫ѐ͘ l_ò̓ϊЫ5NjŐɩҖʌ˾ǣĆ͑Ƙ™̆ºɮŭ1Πщĩě IDEҲϬϊЫ̆ºґ ̫ɩҖÞÞ̛Ĵ Sublime Text ě Vim ɓ̫͘ɩҖƊþιɮ©ɬʁŠʔl´´ȷ϶ї ӁŁǻϬĔЊl ŭ1Ƙ™ϬϊЫɩҖɮʵƤ̫ʿGѹɮїʠѐʌ̫ɽɩl_Ȑ̋ǃlĴλ ɽ5Njş̫͘Ʈʐǜɩlü ǯŭ1 RailscæϬ˞Ы ɬʁëŭ1Ϋɧ̫ Unix ΠщĩїɩNjŹɫŗëίǏcИЁfƘʱĦ˜8ǐ ¹˜ĩ 1.2.2 „İ RubyRubyGemsRails h Git ̠©+ȁɽ̫фVɮɣ˓n̛ƊɮNjҭn̛ȁT̛ȀǫǛфV̛ȀUƝΒnj»Βӎ5Ѕ ɮůϪфVіɮņ¢ Ĵ΋ϥʣѹ_ǺÉǻ0ŶǛůϪϫþ̫ͧɮǻіɮϹͯʆ͒ŭà ʼn – Paul GrahamµέJessica Livingston ϖ ̓ĴþTůϪ Ruby on Rails 5ǻ_ƌҀЂnj˛ ˸cɮ΀Ι*ҖūĴƛƸNjŐĵɟѹþι¬̓ҕӄŠʔl ѯ»ҕӄ̫ЏИѫѐ Google ȿ΂ǼЇҕʄ2̫ƣÍҹҷ Ҧҵɽ̆ʻЗɪlưВn̛ěʄ2 ȁɽфV̷̫Ĉ̫̂ʄÓȠ Railsїʠȃιnj»̷Ĉ̫Δʔɽɩ|Ĉ ̫Ϥ ̂ʄ_C̷̚Ĉ̫Δʔcے̷Ĉ̆ºɮ҂ž Rails ̫̂ʄѐ Ruby ɮoŏ1.9.21.9.3 ě 2.0.0 ѹþT̛:ʄɓ͘ȁTέҩDZѥȟ Rails InstallerWindows TÀĴ Windows ůϪ Rails ɮVNj̧ό̫8cŐ;5 Engine Yard “ă̫œ̃Ŭºɮ Nic Williams àʼně Wayne E. Seguin̓ĴĴ Windows ůϪ Rails î̷–̫фVͮÞŐ5Šʔln̛ Windows ̫ЏþT» Rails Installer ̫Τͤц Rails Installer ůϪ͘ƮҼtþT̺ ůϪϱӃð­ůϪɘVȧ˽ЗɪůϪ GitRuby RubyGems ě RailsůϪŰǺĊlƊþT̶ȷн» 1.2.3 ωëµƶͩ ư̛͘Ʈ5 ɽ ˸ҲϬЗɪn̛ Rails Installer ůϪ̫ Rails ̂ʄþιěҷKΑ̫ɟ˓nj»̫̂ʄ ρїþι_ƀρ ›Ź̫ҕӄ$5ϵ¤їҕӄǻ̓ĴʵĴ Nic ě Wayne гƘkȧ˽ Rails ̂ʄĂ̫ҼƮ²¬  Rails Installer ²ϥ „İ Git Rails ͉× ̫GŐƅѹ_n̛ ý Git1.3 ω _ГΎKΑ̫̂ʄȸ¼΀Ιĭ$œŸѹї(‚ȁTlĴ ƷţƊϬƷţ̛ GitŠhĴln̛̫Ʃÿ ůϪ Git þTìάPro Git2 ̫“ůϪ Git” ω „İ Ruby ȷʌϬůϪ Ruby 5ůϪ̫ѐ͘þιNj̧ό0Źɫ¬Ҍ˜ųǻ0NjŶǛůϪ Ruby ɞ̂ʄѐїɮŭ1̫ ǐΒ*м Njɽþιln̛̫΀ΙƝΒοƢ5 RubylþTȆϡҷ̫ĚSʌ̺  8 ͩ 1 ͥ Mұ»ѸΧ $ ruby -v їĚS_ɯ͈ Ruby ̫̂ʄRails 4 ҲϬn̛ Ruby 1.9 ǼT̫̂ʄcɼşɮ Ruby 2.0Ńʄɣ˓n̛ Ruby 1.8.7ʄɓ͘€ІŐɕ̫Йέn̛̫ɮ Ruby 1.9.3 Ǽ 2.0.0ѐ Ruby 1.9.2 ưВ0þT̛ Šʔln̛̫ɮ OS X Ǽέ LinuxĴůϪ Ruby ɩǻǁ˺ƶϿn̛ Ruby ̂ʄͰ̕Ƙ™ RVMيЄlĴĈ ÿ̞ λůϪƫͰ̕Ő Ruby ̂ʄĴ Windows þTn̛ PikŠʔlơʀĴĈ ÿ̞λ ѓϡĈ̂ʄ̫ Ruby Ǽ Rails ƊҲϬŮ5ŠʔlĴn̛ RVM ɩѯ»H(ҕӄ̫ЏþTĴ RVM ̫ IRC Ӄѱfreenode.net ̫ #rvm БҕŮ̫Ʒòέ Wayne E. Seguin8Šʔln̛̫ɮ LinuxǻȹϐlҘЙ Sudobits àŴ ̫ŠhĴ Ubuntu ůϪ Ruby on Rails ɘ Ĵʶ*ÀOS X ̛ȀþιϬůϪ Xcode ƷòέƘ™̷ž:ůϪɗƘ™ÓǻɹȹϐlůϪчƄ̫ Xcode ĚS ϡƘ™Ó ĴůϪ Ruby *ÀϬůϪ RVM $ curl -L https://get.rvm.io | bash -s ŠʔlƝΒůϪ5 RVMưВѓϡҷ̫ĚS $ rvm get stable ͆wůϪ̫ɮɼɞ̂ʄ ˼Ċѓϡҷ̫ĚSʨʙůϪ Ruby ̫ҲˇʋV $ rvm requirements Ĵǻ̫΀Ι ϬůϪTȁ͈̫Ưn̛ HomebrewOS X ̫ÓͰ̕΀Ι $ brew install libtool libxslt libksba openssl Ĵ Linux þTn̛ apt-get Ǽ yum ǻіnjůϪ YAML Ư # For Mac with Homebrew $ brew install libyaml # For Debian-based Linux systems $ apt-get install libyaml-dev 8. ŠʔlMʂn̛ѐ IRCǻƶϿlȿ΂ “irc client ”OS X ̫ŴȀͦɽ Colloquy ě LimeChatǃ˼ΤҹŴ ȀͦǟɮþTn̛̫ http://webchat.freenode.net/?channels=rvm 9 # For Fedora/CentOS/RHEL Linux systems $ yum install libyaml-devel ɼĊǻϬĔ̾ RVMOpenSSL ̫ůϪdΦȃιůϪ Ruby 2.0.0 $ rvm install 2.0.0 --with-openssl-dir=$HOME/.rvm/usr їʠπƅĴǻ̫΀Ι Ruby 2.0.0 ƝΒǺÉůϪ5 ѐůϪ̫ѐ͘NjŹɫ¬ҌǻƌÇЗɪ5Ƥ̛̫ɟ˓ɹѫ̛̫ɟƻɮqҶȿ΂˼ĊοƜϵ¤ ůϪ Ruby *ĊϬѺΦ l̫΀Ιїʠ˜P͘Ʈȃιѓϡ Railsїѐ͘_ˠî» gem ̫ůϪgem ɮ Ruby R̫̀ȄÓ΀Ιĭ$Ĉ̂ʄ̫ gem _ɽƛƸǻUΒƤϬµƶ ӆŏ̫ gem үgemsetÓď ΀ ²̫ gem҂žʄɓ͘ǻȹϐlµƶ ĉ$ railstutorial_rails_4_0 ̫ gemset $ rvm use 2.0.0@railstutorial_rails_4_0 --create --default Using /Users/mhartl/.rvm/gems/ruby-2.0.0-p0 with gemset railstutorial_rails_4_0 ҷ̫ĚS_n̛ Ruby 2.0.0 µƶ--create ĉ$ railstutorial_rails_4_0 ̫ gemset˼Ċ͢ӋƊ Ʒţn̛use ї gemsetƫƃ˜І$әϻ̫--default gemsetїʠʿʭȄƷɞ̫ΐͦƊ_οÌn̛ 2.0.0@railstutorial_rails_4_0 ї Ruby ě gemset ̫΍ćRVM ȼp5œҀ̫ĚS̛ʌŌ̕ gemsetɹ ՝ŹþTʙ̺˜ɘʦhttp://rvm.io/gemsets/ŠʔlĴn̛ RVM ɩѯ»5ҕӄþTѓϡT̫ĚSɯ͈ƣ ÍxǠ $ rvm --help $ rvm gemset --help „İ RubyGems RubyGems ɮ Ruby һ̴̫ÓͰ̕͘ƮɽNjŐɽ̛̫R̀ƯÓȠ RailsѹþTѫѐÓǼý‚ gem̫Džƻϓ óůϪ Ruby ĊŸůϪ RubyGems ƊNjͮÞ5ŠʔlůϪ5 RVM ƊƝΒůϪ RubyGems 5ĭ$ RVM ƝΒο Ìƃ˜ůϪ5 $ which gem /Users/mhartl/.rvm/rubies/ruby-2.0.0-p0/bin/gem ŠʔlіˎɽůϪ RubyGemsþTц RubyGemsϵéɘV˼Ċј‘ rubygems ̴DŽѓϡůϪ͘Ʈ ruby setup.rb Šʔlѯ»5ʈҤҌЕ̫ȼ͈ì˽ 1.1.3 ωȁЗ̫Ϭn̛ sudo ůϪ RubyGems *ĊϬ͆wln̛̫̂ʄěʄ2 ρ 10 ͩ 1 ͥ Mұ»ѸΧ gem update --system 2.0.0 ƃl̫΀ΙŲʣĴї̂ʄþTѵTĊĭ$ RubyGems ÛΈήC̫̚ƛƸ ůϪ gem ɩәϻǧ¥ RubyGems _̚Ǻ͑Ĉ̫ɘʦri ě rdoccɮNjŐ Ruby ě Rails Ʒòέϻ$ϊɩ Җ̚ǺїAɘʦˎH(ǐϬNjŐ͘ƮĕɹqҶĴ΋ɘʦήɮΦ̫ ri ě rdoc ɘʦ$5͌ʴοÌ̚Ǻɘ ʦǻƶϿlȆϡR̀ 1.1 ̫ĚSĴŸ̴DŽhome directory µƶ ĉ$ .gemrc ̫ gem ѺΦɘVɘV ̫ŹìϮR̀ 1.2˔˞Ă“~”Rϥ“Ÿ̴DŽ”.gemrc ̫˸ĂRϥїɮҪϙɘVѺΦɘV υѹɮҪϙ ̫ R̀ 1.1 µƶ gem ѺΦɘV $ subl ~/.gemrc їѾ̫ subl ɮ OS X đÌ Sublime Text ̫ĚSlþTì˽ Sublime Text 2 ɘʦ ̫ “OS X ĚS” ɘјϡІ ΦŠʔln̛̫ɮ˜P΀ΙǼέln̛̫ɮ˜P̫ΠщĩüҲƠ̇˜P̷ư̫ĚSoŠlþT̶ȷð­ ʌđÌ͘ƮǼέn̛˜P̫ĚSŠ matevimgvim Ǽ mvim$5ϡɘͮ˖Ĵʄ2ĊΛ̫Ź ǃǻ Зn̛ subl ɩǻ̫DZǜɮ“n̛lħş̫ɘʄΠщĩȄƷ” R̀ 1.2 Ĵ .gemrc ѺΦ̚Ǻ ri ě rdoc ɘʦ install: --no-rdoc --no-ri update: --no-rdoc --no-ri „İ Rails ůϪŰ RubyGems ĊůϪ Rails 0ƊͮÞ5ʄɓ͘n̛ Rails 4.0ѫѐTĚSůϪ9 $ gem install rails --version 4.0.0 --no-ri --no-rdoc Šʔlȧ˽ ωȁѝІΦ5 .gemrcƊǐÊɼĊѥһ5cɮǃÀ̫ Rails 4 |ѥ̂ʄǐҽϬÊ ȁTǻȃ¢̫ʨʙ Rails ɮčůϪǺÉȆϡTĚSɯ͈ Rails ̫̂ʄĂ $ rails -v Rails 4.0.0 ˕DZ ŠʔlɮѫѐÀҷKΑ̫ Rails Installer ůϪ̫ Railsȁnj»̫̂ʄĂþι_ɽAĈĴ¢їʄ2̫ɩ| ̂ʄ̫Ĉі_Ƣʌœ̫ҕӄcɮŠʔ Rails ÛΈ»5ɹӑ̫̂ʄҕӄþιƊNjѿ5ǻ̴ÀʵĴě Engine Yard гƘkʌµƶ  Rails Installer ̂ʄ²ϥ Šʔln̛̫ɮ Linux̓ĴǼЄіҲϬůϪ A˜P̫R̀Ó $ sudo apt-get install libxslt-dev libxml2-dev libsqlite3-dev # ü҂ž Linux 9. Ќέ˕ ҁ:IJ̫“͉_%)̆χ”lþιɣ˓ʵƤц gemїɩlþTn̛ VPN Ǽέn̛ RubyGems ĴIJ̫Ґˆ 11 1.2.3 ĉą› Rails ͘Ʈ υѹɮM rails new ĚSƷţ̫їĚS_ĴlȦŲ̫ɘVř µƶ  Rails ͘Ʈʬʎӊ$ l̫ Rails ͘Ʈɞƶ ɘVř˼ĊȆϡ rails new ĚSµƶͩ ͘ƮìϮR̀ 1.3 R̀ 1.3 ѓϡ rails new ̚Ǻ ɞ͘Ʈ $ mkdir rails_projects $ cd rails_projects $ rails new first_app create create README.rdoc create Rakefile create config.ru create .gitignore create Gemfile create app create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb . . . run bundle install . . . Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. ŠR̀ 1.3 ȁ͈ѓϡ rails new ĚS_ĴɘVµƶŰ*ĊοÌȆϡ bundle installŠʔї ʷˎɽʵ͆Ȇ ϡϬȘǏȧ˽ 1.2.4 ω ̫ʷӏʌ‚ưВƊþT5 ɘV/ɘVř ϥʣ 1.1 ͮÞKΑ Rails әϻɘVΔʐ Зɪ app/ ͘Ʈ̫ʡǏɘVÓďʬľϱijȸ¼ĩěƣÍɟ˓ app/assets ͘Ʈ̫ЬˬɘVŠ CSSJavaScript ěij́ bin/ þȆϡɘV config/ ͘Ʈ̫ІΦ db/ ɕȰƯɘV 12 ͩ 1 ͥ Mұ»ѸΧ ɘV/ɘVř Зɪ doc/ ͘Ʈ̫ɘʦ lib/ R̀ƯɘV lib/assets R̀ƯÓď̫ЬˬɘVŠ CSSJavaScript ě ij́ log/ ͘Ʈ̫ɥǒɘV public/ “•oŠ˝ϲĩþЇҕ̫ɕȰŠ¬Ҍҹҷ script/rails ̚ǺR̀ȄƷΐͦ_ЏǼƷđʄĵɿËĩ̫μʄ test/ ͘Ʈ̫˜ЍɘVĴ 3.1.2 ω Ơ̇ spec/ tmp/ #ɩɘV vendor/ ͩɟR̀ŠȽVě gem vendor/assets ͩɟR̀Óď̫ЬˬɘVŠ CSSJavaScript ěij́ README.rdoc ͘ƮͮK Rakefile rake ĚSÓď̫XË Gemfile В͘ƮȁҲ̫ gem Gemfile.lock  gem ̫²ϥ͆wʄ͘Ʈ̫Ŏ¼̂n̷̛Ĉ̂ʄ̫ gem config.ru Rack ҖV̫ѺΦɘV .gitignore git Ụ̫̈́ɘVͶľ ̢DZ  rails ĚSµƶ̫ɘVěɘVřїAʜ¦̫ɘVřěɘVΔʐŠij 1.2ɮ Rails ̫NjŐ^Ñ*  ιϽlMұƷţǕѬ̫µƶ þѓϡ̫ͮÞ̫͘Ʈήĭ$їʠ̫Δʐž Rails ͘Ʈѹɮ ρ̫ҘɘPG ̫R̀ɩƊɯnjNjF°ϥʣ 1.1 ɮїAɘV̫ͮKĴʄ2̫Ċ˝Ź ƃKΑ˜ ̫œŐɕM 5.2.1 ω Ʒ ţӊƃKΑ app/assets ɘVřŮɮ asset pipelineRails 3.1 ɞň̫ Ѹ¯їÉιϽ΍ΏěѸΧ CSS ě JavaScript ͪЬˬɘVõnjƸƤͮÞ 1.2.4 Bundler µƶŰ ɞ̫ Rails ͘ƮĊlþTn̛ Bundler ʌůϪěÓďВ͘ƮȁҲ̫ gemĴ 1.2.3 ω ȼ»ѐrails ĚS_οÌȆϡ Bundlerѫѐ bundle installѐʄωƃž͘ƮәϻÓď̫ gem ‚AyɌ˼ĊŸѓϡ BundlerӊĴlħş̫ɘʄΠщĩ ȄƷ Gemfile ɘV 13 ij 1.2 ɞµƶ̫ Rails ͘Ʈ̫ɘVΔʐ $ cd first_app/ $ subl Gemfile ВɘVŹŠR̀ 1.4їAR̀ƊɮƤϰ̫ Ruby R̀̓ĴɣҲ–˕ú˓ͩīͥƃ_ГΎ̫KΑ Ruby R̀ 1.4 first_app әϻ̫ Gemfile ɘV source 'https://rubygems.org' # Use sqlite3 as the database for Active Record gem 'sqlite3' # Use SCSS for stylesheets gem 'sass-rails', '~> 4.0.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .js.coffee assets and views gem 'coffee-rails', '~> 4.0.0' 14 ͩ 1 ͥ Mұ»ѸΧ # See https://github.com/sstephenson/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby # Use jquery as the JavaScript library gem 'jquery-rails' # Turbolinks makes following links in your web application faster. # Read more: https://github.com/rails/turbolinks gem 'turbolinks' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 1.0.1' group :doc do # bundle exec rake doc:rails generates the API under doc/api. gem 'sdoc', require: false end # Use ActiveModel has_secure_password # gem 'bcrypt-ruby', '~> 3.0.0' # Use unicorn as the app server # gem 'unicorn' # Use Capistrano for deployment # gem 'capistrano', group: :development # Use debugger # gem 'debugger', group: [:development, :test] ˜ NjŐϡR̀ѹ̛ # ˕ѽȳ5їAR̀ɎĴїɮĔЊl AƤ̛̫ gem0ƒ͈5 Bundler ̫ú˓̓ĴҦ 5әϻ̫ gem ǻUіҲϬ˜P̫ gem Šʔ$ gem ĚSȦŲ ̂ʄĂBundler _οÌůϪ gem ̫ɼɞ̂ʄɽA gem ̫ɹɞ_ƢʌΎǎcɽɩ_͂ ĺR̫̀ƛƸȁTĴʄɓ͘ ǻŬDZʑ5þTʵƤѓϡ̫ gem ̂ʄĂŠR̀ 1.5 ȁ͈ĈɩǻU0ƃ˕ѽ ȳ̫R̀ëȳ5 R̀ 1.5 ȦŲ5 gem ̂ʄĂ̫ Gemfile ɘV source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' group :development do gem 'sqlite3', '1.3.7' 15 end gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' gem 'jquery-rails', '2.2.1' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' group :doc do gem 'sdoc', '0.3.20', require: false end R̀ 1.5 ʑ5ҷїϡ ruby '2.0.0' Зɪư̛͘Ʈʁʀn̛̫ Ruby ̂ʄĴѸΧɩ̆ºɽ̛ìϮ 1.4 ωŠʔln̛̫ɮ Ruby 2.0.0ҲϬy Ɍ»ųҠ̫̂ʄĂ ɹɞĊ̫ Gemfile іȏ Rails әϻn̛̫ JavaScript Ư jQuery ̫ gem M gem 'jquery-rails' Ɍ$ gem 'jquery-rails', '2.2.1' Ĉɩ0ƃ gem 'sqlite3' yɌǺ group :development do gem 'sqlite3', '1.3.7' end ǁ¼ Bundler ůϪ sqlite3 gem ̫ 1.3.7 ̂˕DZǻUIȏ SQLite Ɏ»5Ʒò̒Ň 7.1.1 ωїʠþT ѵě Heroku1.4 ω̫ɕȰƯ£͟ R̀ 1.5 0yɌ5˜P©ϡƃ # Use SCSS for stylesheets gem 'sass-rails', '~> 4.0.0' 16 ͩ 1 ͥ Mұ»ѸΧ # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .js.coffee assets and views gem 'coffee-rails', '~> 4.0.0' ɌǺ5 gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' Š̫R̀ gem 'uglifier', '>=1.3.0' _ůϪ 1.3.0 ǼT̫ɼɞ̂ uglifier gemĴ asset pipeline Ō̕ɘV̫é΢ǃ˼0þTůϪ 7.2 ̂ ήҷ̫R̀ gem 'coffee-rails', '~> 4.0.0' ü_ůϪӑ: 4.0.0 ̫̂ coffee-rails0ɮ asset pipeline ̛»̫ȮúЏЗ>= ǟ_ÛΈ»ɼɞ̂ ~> 4.0.0 ü_ÛΈϤ ̂ʄ̫ɹɞoŠM 4.0.0 » 4.0.1ή_ÛΈ»ʭ̂ʄǼ%̂ʄ̫ɹɞoŠM 4.0 » 4.1ѐΒӎĔЊǻUånɮϤ ̂ʄ̫ÛΈ0þι_C̚ҌЕȁTĴʄɓ͘ ǻUŃʄ_$ȁɽ ̫ gem ȦŲɪ̫͆̂ʄĂlþTn̛Xh gem ̫ɼɞ̂ʄіþTĴ Gemfile n̛ ~>ȹϐӑΈ̛Ȁn ̛cǻ8ȼѻlїþι_ƀρʄɓ͘Ʒò̫͘Ʈϥ̓ƸƤ yɌŰ Gemfile Ċѓϡ bundle update10 ě bundle install ůϪȁҲ̫ gem $ bundle update $ bundle install Fetching source index for https://rubygems.org/ . . . bundle install ĚS_ϊЫ ˸ɩҖ ɦΔʉǻU̫͘ƮƊþTѓϡ5 10. їĚSüɽyɌ5 Rails gem ̂ʄɩȃǐҽϬȆϡþιüɽn̛ Rails Installer ȃ_̛»ѐĴ˜Pǧ¥Ȇϡ0ˎɽ ĺŌ 17 1.2.5 rails server ѓϡŰ 1.2.3 ω KΑ̫ rails new ě 1.2.4 ω KΑ̫ bundle install ĊǻU̫͘ƮƊþTѓϡ5cǚ( ѓϡĖ Rails οƢ5 ĚSϡ͘ƮþTĴƷò̞λѓϡ ʄĵɿËĩ 11 $ rails server => Booting WEBrick => Rails application starting on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server Šʔ΀Ιȼ͈Σƅ JavaScript ѓϡɩИ˝ϲ execjs d: github ̫ҹҷʙ̺ Aþѥ̫ѓϡɩǻƶϿůϪ Node.jsѝR̫̀ȼ͈xǠĔЊǻUїư̛͘ƮĴ 0.0.0.0 ĵĸ̫ 300012 ͦøѓϡїĵĸĔЊ΀Ι̯ Đїÿ̞λ̫ʿ þ̛̫ IP ĵĸ υʌЗǻUþTѫѐ ̆ʻ̫ĵĸ 127.0.0.1 ʌʙ̺ư̛͘ƮǼ έ0þTn̛ localhostѫѐ http://localhost:3000 ʙ̺ΔʔŠij 1.3 ȁ͈ ij 1.3 әϻ̫ Rails ҹҷ ˸­“About your application’s environment” þTʙ̺ư̛͘Ʈ̫xǠΔʔŠij 1.4 ȁ͈ij 1.4 ɯ͈̫ɮǾijɩ ǻ̞λ̫̒ŇxǠl̫Δʔþι_ǻ̫Ĉ 11. Š 1.1.3 ω ȁЗĴ Windows ǼЄlϬъ‘ ruby rails server 12. υǧ¥Τͤn̛̫ɮ 80 ͦøcїҲϬ̆º̫ʈҤȁT Rails $ƷòɿËĩѥȟ5 ˎɽôҤ¼̫чœ~ 18 ͩ 1 ͥ Mұ»ѸΧ ǃ˼ǻUɮ̻̫ǯn̛әϻ̫ Rails ҹҷcїҹҷĔЊǻU Rails þTʵƤѓϡ5ǻU_Ĵ 5.3.2 ω ͗Ҧ әϻҹҷ ij 1.4 әϻҹҷ ̫ư̛͘ƮxǠ 1.2.6 às-ijn-¼IkMVC Ĵ¶ʁҜʼʫϲ  Rails ͘Ʈ̫ƘkɟƻŠij 1.5Őƅɮ_ɽAƣÍ̫lþιƝΒ˕DZ»5Ĵ Rails ư ̛͘Ʈ̫ɘVΔʐŠij 1.2 ɽ ɘVřý app/˜ ɽũɘVř modelsviews ě controllersїɶ͈ Rails Ѽ̛5 MVC ʖʐʬƻї͑ʬƻǁ¼ĵƃ“ŁѮщdomain logic”0ý“ËѮ щbusiness logic”ěijDž̛Ȁ̠ҷGUI̫ъ‘ϥ̓Ѯщ¯ƷĴ Web ư̛͘Ʈ “ŁѮщ”̫šľRϥ ɮ“̛Ȁusers”“ɘͥarticles”ě“CĜproducts”ͪɕȰʬľGUI ³ɮ˝ϲĩ ̫Τҹ Ĵ Rails B= ˝ϲĩòѡ ИˇrequestΤΗɿËĩɋ»Иˇƃ˜`ѡ» Rails ̫ȸ¼ĩ˼Ċ¤Ų ʷ‚H(ʗAǧ¥ȸ¼ĩ_͢å˪ʘϱijviewʬʎ̚Ǻ HTML ˼ĊƃΔʔòѡĬ˝ϲĩž:ÌǙΤ ͤʌЗȸ¼ĩ_ěʬľmodelB=ʬľɮ  Ruby žПϥ͈Τͤ ̫ ‹΁oŠ ̛Ȁƫ ТФěɕȰƯѫxЛ̛ʬľĊȸ¼ĩŸ˪ʘϱijƫƃ̚Ǻ̫ HTML R̀ѕĬΖ˝ϲĩ ŠʔlϳnjїAŹɽ˸ȗП̛ȘǏĊҷ_ΒƤЂ» MVCĴ 2.2.2 ω _T˲͈͘Ʈ$oч$ˤ‘̫ϼЅ MVC ĴĊҷ̫œľ͈o͘Ʈ _n̛ MVC ̫’ѸŹ3.1.2 ω ƃKΑȸ¼ĩěϱij6.1 ωƃKΑʬľ7.1.2 ω ƃȏѸ¯ɎĴ гn̛ 19 1.3 ö git 3ïÓ¼I ǻUƝΒµƶ5 þTѓϡ̫ Rails ư̛͘ƮȷʌϬϊ˸ɩҖʌ‚ V8ϝ˼ɮǐҽ‚̫cɮNjŐ Rails ƷòέŃʄѹϻ$їɮưВ‚̫ɼŃʄ̫8ǧїV8Ɗɮƃư̛͘Ʈ̫ˬR̀Ɏ‘̂ʄȸ¼΀Ι ̂ʄ ȸ¼΀ΙþTкпһ̴R̫̀õÔt:ěPGÝkŠʔ¬̓ҕӄoŠƄǏ·Ҧ5ɘVіþTĬˮ»TÀ ̫̂ʄʿфVƷòέѹưВŭ1n̛̂ʄȸ¼΀Ι ̂ʄȸ¼Ƙ™NjŐRails ͉×ɹŐ̫_n̛ gitŮɼ¶ɮ̜ Linus Torvalds Ʒờʌū‡ Linux ʡR̫̀git ̫ ̾ЉNjŐїѾǻUü_KΑ AͮÞ̫ŹΤΗɽNjՐЫ̫ЬəþTҘЙǻ̆ºȹϐ Scott Chacon ̫ Pro GitApress 2009 ƪ¬̂ ɘ̂*ȁTȹϐlƃR̀Ɏ» git ї̂ʄȸ¼΀Ι ɮĭ$ї©+ɮ Rails ͉×̫ɱѰ‚˓іĭ$їʠ‚ɹ¹:R̫̀¯D1.3.4 ω0t:͘Ʈ̫ѸΧ1.4 ω ij 1.5 MVC ʖʐ̫ijϵ 1.3.1 „İ ļġ ŠʔlіˎůϪ gitИȧ˽Àҷ̫KΑјϡůϪŠÀȁѝůϪ̫ѐ͘þTìάPro Git2 ̫“ůϪ Git” ω ĉáœĭÎûļġ ůϪ git ĊlưВ‚ AüҲ‚ ʭ̫8ǧ ΀ΙІΦ——їʠ̫ІΦĴʿÿ̞λüҲ‚ ʭ 20 ͩ 1 ͥ Mұ»ѸΧ $ git config --global user.name "Your Name" $ git config --global user.email your.email@example.com ǻіǯ̛ co RɻŪɕчŐ̫ checkout ĚSѶ(Ϭ‚ŠІΦ $ git config --global alias.co checkout ʄ2 ǻŃʄѹ_n̛Űɗ̫ checkout ĚSқʴlˎɽ‚T̫ІΦcǻοƜѹɮn̛ git co ɼĊlіþTІΦΠщ git ȼBxǠɩn̛̫ΠщĩŠʔln̛̫ɮijDž̠ҷ̫ΠщĩoŠ Sublime Text TextMategVim Ǽ MacVimϬÊ ɢʜ͆wΠщĩ_Ĵΐͦ wȥ̉Ǚήɮ͢ӋΔʉĚS 13 $ git config --global core.editor "subl -w" Šʔn̛˜PΠщĩИn̛TR̀ɻȮ subl -w TextMate ̛ mate -wgVim ̛ gvim -fMacVim ̛ mvim -f ļġĉ"œ ҷ̫ʷӏlʿʭɞƶ NƯɩѹϬȆϡӊј‘´µƶ̫ư̛͘Ʈ̫ʢ̴DŽ˼Ċ¶ţÔ ɞNƯ $ git init Initialized empty Git repository in /Users/mhartl/rails_projects/first_app/.git/ ȷʌϬƃһ̴̫ɘV˦Ê»NƯ ѐɽ ˸ϬЗɪ  git әϻ_кпȁɽɘV̫õÔcɮɽAɘVǻU ƫǯкпoŠRails _µƶ AɥǒɘVЁDŽư̛͘Ʈ̫ÌkїAɘVΒƤõÔǻUƫҲϬ̂ʄȸ¼΀ ΙкпїAɘVgit ɽỤ̈́ɘV̫ʆ¼ Ĵư̛͘Ʈ̫ʢ̴DŽµƶ ĉ$ .gitignore ̫ɘV˼Ċ¢‘ A ϰ³ĔЊ git ϬỤ̈́ĠAɘVåþ14 ̺ Àҷ̫ϥʣ 1.1rails ĚSәϻ_Ĵư̛͘Ʈ̫ʢ̴DŽµƶ .gitignore ɘV˜ŹŠR̀ 1.6 ȁ͈ R̀ 1.6 rails ĚSәϻµƶ̫ .gitignore ɘV # See http://help.github.com/ignore-files/ for more about ignoring files. # # If you find yourself ignoring temporary files generated by your text editor # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile '~/.gitignore_global' # Ignore bundler config. /.bundle 13. ї˜ųɮ ̆ǝĭ$đÌΠщĩ*ĊlþTΚΛn̛ĚSϡѐ git Ȇϡ͘ƮĴν͎Ċ_–ҔɘVѕĬ ͝xǠ їƊҝ͇5ȼB̫јϡǻĴїѾȼ»ї ˸ɮĭ$ŠʔЗlĴn̛ subl ě gvim ɩƊ_įǩ$H(ϡѫŠʔlò̓ї ˕ѽNjҭǷѶƊےỤ̈́ŮĎ 14. Šʔlˎɽ̺» .gitignore ɘVǼЄlҲϬІΦ ϽɘVʙ̺ĩɯ͈ҪϙɘV 21 # Ignore the default SQLite database. /db/*.sqlite3 /db/*.sqlite3-journal # Ignore all logfiles and tempfiles. /log/*.log /tmp R̀ 1.6 ̫R̀_Ͻ git Ụ̈́ɥǒɘVRails ̫#ɩɘVtmp/ě SQLite ɕȰƯ$5Ụ̈́ log/ ɘVř ̫ɥǒɘVǻƯ log/*.log ʌỤ̈́ȁɽT .log Δƍ̫ɘVœѸ¯ϧỤ̫̈́ɘVѹɮõÌӃ΅ήɮο ̵ƶ̫ˎǐϬȏїAɘVΊ‘̂ʄȸ¼ήǃěPGÝkɩїAɘVіþι_ƀρ£͟ R̀ 1.6 ̫R̀üɮ҂žʄɓ̫͘cɮ΀Ι ̫ AɘV0ϬỤ̈́R̀ 1.7 ³ɹ$’ҷňǁĊ̫ .gitignore ɘV_Ụ̈́ Rails ư̛͘Ʈ̫ɘʦVim ě Emacs ̫BȮɘVswap fileTî Mac Finder ͘Ʈ̚ Ǻ̫АƸ̫ .DS_Store ɘV҂ž OS X ̛ȀŠʔlǯn̛їɹ’ҷ̫Ụ̈́ɘV̛lħş̫ɘʄΠщĩ ȄƷ .gitignore ɘV˼Ċ¢‘R̀ 1.7 ̫R̀ R̀ 1.7 Êǁ̂ .gitignore ɘV # Ignore bundler config. /.bundle # Ignore the default SQLite database. /db/*.sqlite3 /db/*.sqlite3-journal # Ignore all logfiles and tempfiles. /log/*.log /tmp # Ignore other unneeded files. doc/ *.swp *~ .project .DS_Store .idea 1.3.2 éLÉ(š¾ ɼĊǻUϬȏ Rails һ̴ ̫ɘV˦Ê» git ˼ĊȼBΔʔlþTn̛ѝĚS˦Êȁɽ̫ɘVҦ5 .gitignore Ụ̫̈́ɘV $ git add . 22 ͩ 1 ͥ Mұ»ѸΧ їѾ̫˸Ă.RϥǃÀ̴DŽgit _οÌ̫ƃȁɽ̫ɘVÓȠũ̴DŽ ̫ɘV˦Ê» git їĚS_ƃһ̴ ̫ɘV˦Ê»ɵūףstaging areaїףÓďʂȼB̫ɌÌlþTn̛ status ĚSʙ̺ɵūףɽĠ AɘV 15 $ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached ..." to unstage) # # new file: README.rdoc # new file: Rakefile . . . ɯ͈̫ΔʔNjґȁTǻ̛˸ĂRɻ5 ̛ commit ĚSĔЊ git lǯwūїAɌÌ $ git commit -m "Initial commit" [master (root-commit) df0a62f] Initial commit 42 files changed, 8461 insertions(+), 0 deletions(-) create mode 100644 README.rdoc create mode 100644 Rakefile . . . ɢʜ -m ŠЄl$їʭȼB˦Ê xǠŠʔˎɽȼp -mgit _ȄƷlĴ 1.3.1 ω ІΦ̫ΠщĩlҲϬĴΠ щĩ ņ¢xǠ ɽ ˸NjѿϬgit ȼBɮ҂žʄĵ̫ɕȰüūĴȆϡȼB̫̞λ ї ˸ěû Njϖĉ̫Ʒˬ̂ʄȸ¼΀Ι SVN ĈSVN ȼBɩ_ɹɞљ͘NƯgit ƃ SVN ̫ȼB¯Ǻ5Ѹ¯ ʄĵwū̫ɹɌgit commitě ƃɹɌȹѡ»љ͘NƯgit pushĴ 1.3.5 ω _˲͈ȹѡї ʷ ҼtЗ lþTn̛ log ĚSʙ̺ȼB̫èĀxǠ $ git log commit df0a62f3f091e53ffa799309b3e32c27b0b38eb4 Author: Michael Hartl Date: Thu Oct 15 11:36:21 2009 -0700 15. ŠʔTĊlȆϡ git status ̺» AҲϬ̫ɘV¬̓5lƊþTƃ˜Ê‘l̫ .gitignore ɘV  23 Initial commit ŠʔϬѠ¬ git logъ‘ q 1.3.3 git ­'—Öx ̓Ĵlþιіɮے˧ʪƃˬ̀Ί‘̂ʄȸ¼΀ΙɽH(şŌѶǻƊ&oũʌЗɪ ĎĊΛͥω і ɽNjŐoũ€ІlƄǏ‚5 AɌÌˀŠЗ·Ҧ5 app/controllers/ ɘVř $ ls app/controllers/ application_controller.rb $ rm -rf app/controllers/ $ ls app/controllers/ ls: app/controllers/: No such file or directory ǻƯ Unix ̫ ls ĚS²¬ app/controllers/ ɘVř ̫Ź̛ rm ĚS·ҦїɘVřɢʜ -rf ̫DZ ǜɮ“ǁ¼Ѩǂ”ɣҲnj»͆ϻƊѨǂ̫·ҦȁɽɘVɘVřũɘVřͪ ʙ̺ ̉Ǚ̺̺ò̚5H( $ git status # On branch master # Changed but not updated: # (use "git add/rm ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # deleted: app/controllers/application_controller.rb # no changes added to commit (use "git add" and/or "git commit -a") þT̺» ɘVϧ·Ҧ5cɮїɌÌüò̚ĴƘk×іˎɽȼBїʠǻUƊþTn̛ checkout ĚS° Ȯ»À ȼBЁDŽʌɅ҉їʭɌ̘ ɢʜ -f DZǜɮϭ̱ǃÀ̫ɌÌ $ git checkout -f $ git status # On branch master nothing to commit (working directory clean) $ ls app/controllers/ application_controller.rb ·Ҧ̫ɘVřěɘVíĬʌ5їɎǏ5 24 ͩ 1 ͥ Mұ»ѸΧ 1.3.4 GitHub lƝΒƃһ̴̫R̀Ί‘ git ̂ʄȸ¼΀Ι5̓ĴþTƃ˜ȹѡ» GitHub 5GitHub ɮ ҂ž Git NƯ̫ū‡ î¯D͉BƩÿƃR̫̀ȡСū YĴ GitHub ɽ̴̫ ˜ ɮžR̫̀ŰɗōYÓȠŰɗ̫ȼBè Ā˜9ɮɟtTĊ̫Ýkї ʷɮǐҽϬ‚̫ѐʑ GitHub þTΖlȼpʆ_ì»ɹƭ$G̫̾ Ʒˬһ̴  GitHub ɽ AɋЫ̫Ϲ±cɮžƷˬһ̴̫R̀ɮЫ̫Šʔlіˎɽ GitHub ̫ЦȀƊвǕ˕ž Ы̫ ЦȀĎǼЄlϬìά GitHub ̫“µƶ SSH źÕ” ɘ˕žĊ˸­µƶNƯ̫҈ȷNew repository˼ Ċņ‘ȁҲ̫xǠŠij 1.6 ȁ͈˕DZϬѥȟn̛ README ɘV¶ţÔNƯInitialize this repository with a READMEĭ$ rails new ƝΒο̵ƶ5їɘVȼBϥÞĊȧ˽ҷ̫ɟ˓ƃlͩ ư̛͘Ʈȹ ѡë $ git remote add origin git@github.com:/first_app.git $ git push -u origin master ij 1.6 Ĵ GitHub µƶͩ NƯ ҷ̫R̀ĔЊ Git lϬ˦Ê GitHub ҷ̫NƯĵĸ$R̫̀êʄRϥʄĵ̫%¯Ɋmaster˼Ċƃʄĵ ̫NƯȹѡ» GitHub Ϭ–Ǐɢʜ -u ̫k̛ŠʔlųĴşŚþTȿ΂“git set upstream”ǃ˼lϬȏ ȮǺl̻ʵ̛̫ȀĉoŠǻȆϡ̫ĚSɮ 25 $ git remote add origin https://github.com/mhartl/first_app.git ˼ĊĴ GitHub Ɗɽ5їư̛͘ƮNƯ̫ҹҷҹҷ ɽɘV˝ϲÉιÓď5Űɗ̫ȼBèĀіɽ A˜P ş̫̑ÉιŠij 1.7 GitHub іȼp5ňǁĚSϡ̠ҷ̫Ƙ™Šʔlɹħʮn̛ GUI ͘ƮþT» GitHub for Windows ě GitHub for Mac ҹҷцGitHub ҂ž Linux ̫Ƙ™̺ʠũƊɮ Git ʄс5 ij 1.7 GitHub NƯҹҷ 1.3.5 BÄĞŏ¾`š Šʔlȧ˽ 1.3.4 ω ȁЗ̫‚5ǼЄƝΒ˕DZ»5GitHub ĴNƯ̫%ҹҷ_οÌɯ͈ README ɘV̫Ź ĴїѾĭ$һ̴ɮn̛ rails ĚS̚Ǻ̫ї README ɮ Rails οƢ̫Šij 1.8ʢȰ .rdoc ȇƒĉ GitHub _ȧ˽ Ų̫ʣƻɯ͈˜Źcɮ˜ŹʄсƫˎɽH(DZ)ĴʄωǻUƃ‚ͩ ʭΠщyɌ README ɘV̫ŹʌȻѝǻU̫һ̴ήɮ Rails ʤʖĴΠщ̫ѐ͘ lþT̺»¯ɊΠщȼBćƫ̫Ƙ k˚ǻȹϐlĴ Git n̛їʠ̫Ƙk˚ 26 ͩ 1 ͥ Mұ»ѸΧ ij 1.8 GitHub ɯ͈̫һ̴¶ţ̚Ǻ̫ README ɘV BÄ Git ̫¯ɊÉιNjǁœ¯ɊɮžNƯ̫Ŏ¼Ĵ¯Ɋ ȁ‚̫ɌÌǼЄɮųӎǝЧ̫_džĞ˿ΈɘV œŐɕǧ¥˿ΈNƯɮ master ¯ɊǻUþTn̛ checkout ĚSƫȦŲ -b ɢʜµƶ ɞ¯Ɋ $ git checkout -b modify-README Switched to a new branch 'modify-README' $ git branch master * modify-README ͩ9ĚSgit branch_ƃʄĵȁɽ̫¯Ɋ²¬ʌ¯ɊĉÀҷ̫ɬĂ*ȦɪǃÀȁĴ̫¯Ɋ˕DZ git checkout -b modify-README _µƶ ɞ¯Ɋ˼Ċ°Ȯ»ї¯Ɋmodify-README Àҷ̫ɬĂ Јɪ5ї ˸ŠʔlĴ 1.3 ω ІΦ5ºĉ coѶ(lƊϬn̛ git co -b modify-README 5 ¯Ɋ̫ġ W~ɮĴŐƷòGĕÝĈƷò һ̴ɩnƷò̫ѐ͘ɹɪ516ѐžüɽ Ʒòέ̫һ̴ˀ Šʄɓ͘0ɽ̛ υήϷ%¯ɊɮěM¯Ɋҫ͎Ʒ̫ȁTåtǻUɀ̓50üҲ°ȮĬ»%¯Ɋƫ·ҦM ¯ɊʌȳɌÌĴʄωʃƍǻU_̺»ǚ(‚ 16. ɹ՝ŹИʙ̺Pro Git2 ̫“Git ¯Ɋ ɘ̂”Ѹ¯ 27 ҼtЗ ž:чƄ̫ɌÌǻ υ_Ì̛ɞ¯ɊїѾɮžş̫1ǭ‚ ˲͈ Ğŏ µƶ5M¯ɊĊǻUϬΠщɘVϽ˜ɹş̫ȻѝǻU̫һ̴ч*әϻ̫ RDoc ʣƻǻɹħʮ Markdown ʜЁ ДϷŠʔɘVȇƒĉɮ .mdGitHub _οÌ$lȵ̂ӊǻUn̛ Unix ĚS mv͗Ìmove̫ git ̂ʄʌ yɌɘVĉ˼Ċ¢‘R̀ 1.8 ȁ͈̫Ź $ git mv README.rdoc README.md $ subl README.md R̀ 1.8 ɞ̫ README ɘVREADME.md # Ruby on Rails Tutorial: first application This is the first application for the [*Ruby on Rails Tutorial*](http://railstutorial.org/) by [Michael Hartl](http://michaelhartl.com/). ¾ ΠщĊʙ̺ В¯Ɋ̫̉Ǚ $ git status # On branch modify-README # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # renamed: README.rdoc -> README.md # # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: README.md # їɩǻUþTn̛ 1.3.2 ω ̛»̫ git add .cɮ Git ȼp5ɢʜ -aŮ̫DZǜɮƃ̓ɽɘV̫ȁɽɌÌ ÓȠn̛ git mv µƶ̫ɘVž Git ʌЗїƫɮɞ̫ɘV˦Êјʌ $ git commit -a -m "Improve the README file" 2 files changed, 5 insertions(+), 243 deletions(-) delete mode 100644 README.rdoc create mode 100644 README.md 28 ͩ 1 ͥ Mұ»ѸΧ ÚºЕ̛5 -a ɢʜŠʔĴʭȼB*Ċlċһ̴˦Ê5ɞɘV̫ЏӊlϬn̛ git add ĔЊ Git l˦Ê ̫ɘV ˕DZȼB̫xǠǻƯ̫ɮ̓ĴɩGit ƃȼBk$ ΀²ȄϤ ̫˘ÌĴї͑ǧ¥Зɪ̓Ĵ‚5H(ˀЗ ɪѐë‚5H(Ϭɹć̕ήї̛͑˓ě Git ̚Ǻ̫ȼBxǠɹÖѺɹŐxǠИʙ̺ GitHub ̫àɘShiny new commit styles `š ǻUƝΒyɌŰ5̓ĴþTƃ˜ćƫ»%¯Ɋ5 $ git checkout master Switched to branch 'master' $ git merge modify-README Updating 34f06b7..2c92bef Fast forward README.rdoc | 243 -------------------------------------------------- README.md | 5+ 2 files changed, 5 insertions(+), 243 deletions(-) delete mode 100644 README.rdoc create mode 100644 README.md ˕DZ Git ΒƤ_ɯ͈Ͷb 34f06b7 ̫Ūͨїɮ Git ѸžNƯ̫ȦRlnj»̫ъ¬Δʔ_ěǻ̫ ʬ ʠ cœρ̷Ĉ ćƫŰĊǻUþT˧̕ ¯Ɋ5n̛ git branch -d ·ҦїM¯Ɋ $ git branch -d modify-README Deleted branch modify-README (was 2c92bef). ї ʷɮþѥ̫8ų υǻUѹ_̢̽їM¯ɊїʠlƊþTĴ%M¯Ɋ*ҖʌĬ°ȮĴćѢ̫ɩ| ƃɌÌćƫ»%¯Ɋ  ŠÀҷȼ»̫lþTn̛ git branch -D ɎƹžM¯Ɋȁ‚̫yɌ # For illustration only; don't do this unless you mess up a branch $ git checkout -b topic-branch $ $ git add . $ git commit -a -m "Major screw up" $ git checkout master $ git branch -D topic-branch ěɢʜ -d Ĉånіʂćƫ -D 0_·Ҧ¯Ɋ 29 ½ŗ ǻUƝΒɹɞ5 README ɘVþTƃɌÌȹѡ» GitHub ̺̺ɌÌ̫Δʔĭ$*ÀǻUƝΒȹѡѐ ʭ5 1.3.4 ωĴœŐɕ΀Ι ǻUѹþT̹̣ origin masterüϬѓϡ git push $ git push ʵˆǻUKΑ̫GitHub n̛ Markdown ϵʑĩžɘVјϡ5ȵ̂Šij 1.9 ij 1.9 n̛ Markdown ȵ̫̂Ɍј̂ README ɘV 1.4 ŞĢ ån̓ĴіŌĴɨʁҜʼǻUіɮϬƃǻUˎH(Ź̫ Rails ư̛͘ƮѸΧ»̚C̒Ňї ʷɮþѥ ̫ѐĴƷòѐ͘ ƌɨӃ΅̫ѸΧþTƌɨ̫ò̓Ʒò ̫ҕӄĴƷò̒Ň ʏÇϵ¤ҕӄ*ĊŸѸΧ,ͪ »òƞɥʁ»ʌɩΒƤ_ƀρѿ̫ҕӄ17 17. ϝ˼҂žʄ2̫͈o͘ƮlɣҲ–ǏѐŠʔlNjȘǏŕɨ̫ƃl̫ư̛͘Ʈ“ƷìάĴ 1.4.4 ω ȼp©ɟ˓ 30 ͩ 1 ͥ Mұ»ѸΧ ѐëѸΧ Rails ư̛͘ƮɮNj̧ό̫8cɼє©ƪ Rails ƷòΩgɜ̫Ǻ˾̓ĴɽNjŐş̫ϵ¤ɟʥ5їA ɟʥÓȠѓϡ Phusion PassengerApache ě Nginx18 ΤΗɿËĩ̫ ʬĻ̫•D%ʆǼ͐ɽϜȝɿËĩ Engine Yard ě Rails Machine ї͑ȼp’ɟdѸΧɿË̫“ăEngine Yard Cloud ě Heroku ї͑<ѸΧɿË ǻɼħʮ̫ѸΧɟʥɮ Herokuїɮ ̆º҂ž Rails ě˜P Ruby Web ư̛͘Ʈ19̫ȅͰƩÿHeroku Ͻ Rails ư̛͘Ʈ̫ѸΧõnjƸƤͮÞüϬl̫ˬ̀Ί‘5 Git ̂ʄȸ¼΀ΙƊşї0ɮ$H(lϬȧ˽ 1.3 ω K Α̫ʷӏůϪ Git ̫êĭŠʔlіˎɽůϪƊвǕůϪĎʄωҷ̫ŹƊɮKΑŠhƃǻU̫ͩ ư̛ ͘ƮѸΧ» Heroku 1.4.1 Àž Heroku ŞĢòv Heroku n̛ PostgreSQLòҸ post-gres-cue-ellΒƤ͖ͮ PostgresȁTǻUϬȏ pg ʑ̚C΍Rails ȃιě PostgreSQL ѫx group :production do gem 'pg', '0.15.1' end ǻUĴ 1.2.4 ωЗѐɼşȦɪư̛͘Ʈʁʀn̛̫ Ruby ̂ʄ ruby '2.0.0' Šʔln̛̫ɮ Ruby 1.9.3ƊϬɌǺ ruby 1.9.3žʄɓ͘ʌЗї̂ʄ_ɽŕœ×ºĴR̀ 1.5 ̫Ń̈́kѝyɌnj»R̀ 1.9 R̀ 1.9 ˦Ê5 pg ƫȦŲ5 Ruby ̂ʄ̫ Gemfile source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' group :development do gem 'sqlite3', '1.3.7' end gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' gem 'jquery-rails', '2.2.1' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' 18. òҸ$“Engine X” 19. Heroku þTʵƤѓϡXDZ n̛ Rack ҖV̫ Ruby Web ͘ƮRack $ Web ʤʖě Web ɿËĩ*Җȼp5ʜ¦ȷø Ruby ͉×Njʣ̫ȍϨ5ї ʜ¦NjŐʤʖѹɮїʠ‚̫oŠ SinatraRamazeCamping ě Railsї0ƊDZĘ̽ Heroku ŃʄɊȥȁɽ̫ Ruby Web ư̛͘Ʈ 31 group :doc do gem 'sdoc', '0.3.20', require: false end group :production do gem 'pg', '0.15.1' end ůϪїA gemϬȆϡ bundle installƫȦŲɢʜ $ bundle install --without production ȦŲ --without production Ċʄĵ̒ŇƊ_ůϪ̚C̒ŇȁҲ̫ gem 5žʄoʌЗƊüɽ pg  gem Šʔ Bundler ɯ͈  readline ̷–̫ҌЕИȏ gem rb-readline ʑ Gemfileĭ$ǻU˦Ê̫ gem ü҂ž̚C̒ŇȁT̓ĴȆϡїĚS_ĴʄĵůϪXh gemcї ʷæɮǐҽ̫ĭ$ǻUϬȏ pg ě Ruby ̂ʄɹɞ» Gemfile.lock їʠ Heroku ȃ̾ѱư̛͘ƮϬn̛̫ Ruby ̂ʄ˼ĊȼBѝɌÌ $ git commit -a -m "Update Gemfile.lock for Heroku" ˼ĊϬ˕žƫІΦ ɞ Heroku ЦȀͩ ʷɮ˕ž˼Ċʙ̺ѷͲŰǺ˕žŸn̛ Heroku Toolbelt ůϪȁ Ҳ̫фVȷ̽ȄƷĚSϡѫѐ heroku ĚS̨DŽ $ heroku login ɼĊĬ» Rails ư̛͘ƮȁĴ̴DŽn̛ heroku ĚSĴ Heroku ̫ɿËĩµƶ ףɎΦl̫ư̛͘Ʈì ˽R̀ 1.10 R̀ 1.10 Ĵ Heroku ɞƶ ư̛͘Ʈ $ cd ~/rails_projects/first_app $ heroku create Created http://stormy-cloud-5881.herokuapp.com/ | git@heroku.com:stormy-cloud-5881.herokuapp.com Git remote heroku added heroku ĚS_$l̫ư̛͘Ʈɞƶ ũŁĉ͢ӋƊþT̚ɐǃ˼̓Ĵі̺»ŹϽǻUƷţѸΧ Ď 1.4.2 Heroku ŞĢĉã ϬѸΧ» Herokuͩ ʷɮѫѐ Git ƃư̛͘Ʈȹѡ» Heroku $ git push heroku master 32 ͩ 1 ͥ Mұ»ѸΧ ij 1.10 ʄɓ̫ͩ͘ ư̛͘ƮѓϡĴ Heroku  1.4.3 Heroku ŞĢĉã 8ųˎɽͩ9ʷ5ǻUƝΒŰǺѸΧ5Šij 1.10lþTѫѐ heroku create ĚSΖ¬̫ĵĸì˽R ̀ 1.9cѶѾ̫ĵĸɮǻ̫ư̛͘Ʈ̫ʙ̺l´´ѸΧ̫ư̛͘Ʈ5lþTċ heroku ĚS`Ѩ ìɕʌ Ͻ˜οÌđÌ˝ϲĩƫȄƷl̫ĵĸ $ heroku open Ϳͽɯ͈̫ɮ ҌЕҹҷž Rails 4 ʌЗ̜:ȎʅêĭHeroku ɣ˓ɯ͈әϻҹҷƬşǃǻUĴ 5.3.2 ω ˦Êкм̜ĊҌЕƊ_˟ŗ5 ѸΧǺÉĊHeroku _ȼp NjͻΨ̫̠ҷͰ̕ěІΦl̫ư̛͘ƮŠij 1.11 1.4.4 Heroku û;#g% Heroku ȼp5NjŐĚSʄ2üKΑ5©Ńʄ̫ҷŸKΑ ĚS̛ʌѿĚĉư̛͘Ʈ $ heroku rename railstutorial 33 ij 1.11 Heroku ȼp̫ͻΨ̠ҷ lϬŸn̛їĉŪ5ǻƝΒn̛58ų̓ĴlɣҲ‚їʠ̫yɌn̛ Heroku ȼp̫әϻ~Ɗϡ ѐŠʔl̻̫ǯѿĚĉl̫ư̛͘ƮlþTŃ:ů’̫άϛn̛ AҩʆǼҭ̎˜»̫ĉŪoŠ hwpcbmze.herokuapp.com seyjhflo.herokuapp.com jhyicevg.herokuapp.com n̛їʠҩʆ̫ŁĉüɽlƃĵĸĔЊºGPUȃιЇҕl̫ΤͤҼtЗ Ͻl ͡ Ruby ̫ǁœT ɮǻ̛ʌ̚ǺҩʆŁĉ̫R̀NjͻšĎ ('a'..'z').to_a.shuffle[0..7].join Ҧ5ɊȥũŁĉHeroku 0ɊȥοŲ)Łĉ8ųʄ2̫Τͤ20ƊɎĴ Heroku ŠʔlҘЙ̫ɮʄ2̫Ĵ ΋̂l̓ĴƊʵĴ˝ϲ ȅͰĴ Heroku ̫ΤͤĴ Heroku ɘʦ þTʙ̺ɹՖ:οŲ)Łĉ̫xǠT î˜P Heroku ̷–̫Џӄ 20. Ќέ˕ ύɘ̂ê2̫ΤͤȅͰ: Herokuʄ ɘ̂Ĵ Githubhttp://railstutorial-china.org 34 ͩ 1 ͥ Mұ»ѸΧ 1.5 ŒĘ ї ͥ ‚̫8ǧ̻ƅ ůϪɁƶƷò̒Ň̂ʄȸ¼TîѸΧŠʔl̓Ĵǯ¯DҘЙʄ2̫јƴlþT ò ʋȹǼέɹɞ Facebook ̉Ǚ¢Ͷbҷ̫Ź ǻʵĴҘЙ @railstutorial ŭ1 Ruby on Rails http://railstutorial.org/ 35 ʶҹ̢̩ ͩ 2 ͥ ˲͈͘Ʈ ĉ 2 ć íāą› ʄͥǻUϬƷò ͮÞ̫˲͈ư̛͘Ʈʌƒ͈  Rails ǁœ̫ÉιǻU_n̛μȂʖscaffoldÉιǕѬ̫ ̚Ǻ͘ƮїʠƊιT Ų̫ӑƴʫϲ  Ruby on Rails Π̫͘ѐ͘0ιœρ̫5ϵ  Web ƷòʵŠĴ ͩ ̫ͥɡ˕ 1.1 ȁЗʄ2ƃѼ̛û ͑ɟ˓ǻU_ǍƮ˨ј̫Ʒò͘Ʈѯ»ɞ̫ʫǖѹ_ГΎЗɪ ѐ$5ʫϲÉι0$5ſȌǺƊdz0ɣҲžμȂʖѵήМǻUþTѫѐ URL ěɼΐ̫˲͈͘ƮјϡB =5ϵ  Rails ư̛͘Ʈ̫Δʐ0ͩ ʭ˲͈ Rails n̛̫ REST ʖʐ ěĊҷ̫œľ͈o͘ƮͶbї˲͈͘ƮƃÓď̛Ȁusersěǎàmicropostsʬľĭʶų̓5 Ƅ ľ̫ Twitter Ͷ͘Ʈ͘Ʈ̫ÉιіҲϬĊΛ̫ƷòήƷòѐ͘ ̫NjŐʷӏ̺гʌ0Nj͔͋ѐɵɩ̛ ȘǏ MͩͥгƃMұƷţŸƷò Ͷb̫͘Ʈǻі_ȼpœҀ̫ЬəpĊΛìάlϬɽAίǏϬǛ Ő̈ҌЕʄ̫ͥ%Ϭ̴̫ƊɮϽlϬϧμȂʖ̫͋Śўǩf5ήϬɹˤ‘̫5ϵ Rails 2.1 IJCą› Ĵї ωǻUϬϰ± ї˲͈͘Ʈě 1.2.3 ωͶbǻUn̛ rails ĚS̚Ǻ͘Ʈ̫Ӑʖ $ cd ~/rails_projects $ rails new demo_app $ cd demo_app ˼ĊǻƯ ɘʄΠщĩyɌ Gemfile¢‘R̀ 2.1 ȁ͈̫R̀ R̀ 2.1 ˲͈͘Ʈ̫ Gemfile source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' group :development do gem 'sqlite3', '1.3.7' end gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' gem 'jquery-rails', '2.2.1' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' 37 group :doc do gem 'sdoc', '0.3.20', require: false end group :production do gem 'pg', '0.15.1' end ˕DZR̀ 2.1 ěR̀ 1.9 ɮ ʠ̫ ě 1.4.1 ω ʠĴʄĵůϪ gem ɩȦŲ --without production ѥһůϪ̚C̒ŇȁҲ̫ gem $ bundle install --without production $ bundle update $ bundle install ŸʭȼѻŠʔ Bundler ȼ͈ ě readline ɽ–̫ҌЕИĴ Gemfile ʑ gem rb-readline ij 2.1 $˲͈͘ƮĴ GitHub ɞƶ NƯ ɼĊǻUіϬȏ˲͈͘ƮΊ‘̂ʄȸ¼ȼѻ rails ĚS_̚Ǻ әϻ̫ .gitignore ɘVѐž: lȁn̛̫΀ΙήϷR̀ 1.7 ̫R̀b+ɹɽ̛˼Ċ¶ţÔ  Git NƯ‚ͩ ʭȼB 38 ͩ 2 ͥ ˲͈͘Ʈ $ git init $ git add . $ git commit -m "Initial commit" lþTѿɞµƶ NƯ˼ĊƃR̀ȹѡ» GitHub $ git remote add origin https://github.com//demo_app.git $ git push -u origin master ěͩ ͥ ̫͘Ʈ ʠ˕DZϬn̛ GitHub οÌ̚Ǻ̫ README ɘV¶ţÔNƯ ҷϬƷòї͘Ʈ5Ʒò Web ư̛͘Ʈ υʌЗͩ ʷɮµƶɕȰʬľdata modelʬľRϥư̛͘Ʈȁ Ҳ̫ΔʐžǻUї͘ƮήϷŮɮхàŴɽ̛ȀěǎàѶ(ǻU$͘Ʈµƶ ̛Ȁusersʬľ 2.1.1 ω˼ĊŸ˦Êǎàmicropostsʬľ2.1.2 ω 2.1.1 ö®às Ĉ̫˕žϥÞRϥ5Ĉ̛̫ȀɕȰʬľǻUƃѥȟ ͑ͮÔ̫ʬľї˲͈͘Ʈ̛̫ȀϬɽ ġ ̫ʜ Љͨ idɗɕ integer žŏɯ͈̫ĉŪ nameŪͨ" stringіɽ  Email ĵĸ emailŪͨ " stringŮƃĈɩ›X̛Ȁĉ̛Ȁʬľ̫ΔʐŠij 2.2 ij 2.2 ̛ȀɕȰʬľ ǻU_Ĵ 6.1.1 ω KΑij 2.2 ̫ʜͭ users RϥɕȰƯ ̫ ϥidname ě email ɮϥ ̫² 2.1.2 ¦Sàs ǎàɕȰʬľ̫ʡǏˀ̛Ȁ̫ʬľіϬͮÞ ǎàϬɽ  id ě Ź contentŪͨ" string1 ѐ іɽ ˀчŎʇ̫ɕȰϬų̓ ƃǎàě̛Ȁ–γгʌǻUn̛ user_id ʌū‡ǎà̫Ȟɽέɼΐ̫ɕȰ ʬľŠij 2.3 ij 2.3 ǎà̫ɕȰʬľ Ĵ 2.3.3 ω ǻU_̺»ǚʠn̛ user_id ŪʼͮÞ̫ų̓ ̛ȀȞɽŐǎà̫Éιͩ 10 ͥ_‚ɹГƌ̫ KΑ 1. ŠʔϬų̓Źɹґ̫ɘͥoŠ ͳƤϰàŴ ̫ɘͥưВƃŪͨ"ͶľstringȮǺɘʄͶľtext 39 2.2 Users ʼnìusers resource ʄωǻUƃϬų̓ 2.1.1 ω ІŲ̛̫ȀɕȰʬľі_$їʬľµƶŃ:Τҹ̫̠ҷї9έΔćгʌƊɮ “Users Ьˬ”“Ьˬ”̫DZǜɮƃ̛ȀІǯ$žПþTѫѐ HTTP ÝϿĴΤҹ µƶcreateЙóread ɹɞupdateě·ҦdeleteʵŠÀҷȼ»̫ǻU̫ Users Ьˬ_n̛μȂʖÉι̚ǺRails Φ5їʠ̫ Éιǻǁ˺ƶϿlϬΎ̺̚Ǻ̫R̀Ĵїɩ|̺ü_Ͻlɹįǩ ƃ scaffold `ѨΖ rails generate ƊþTn̛ Rails ̫μȂʖÉι5`Ζ scaffold ̫ìɕɮЬˬĉ̫Þ ɕDžƻʄo Ɗɮ UserĊҷþTŸк̽ȦŲɕȰʬľ̫Ūʼ 2 $ rails generate scaffold User name:string email:string invoke active_record create db/migrate/20130305221714_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route route resources :users invoke jbuilder_scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke test_unit create test/helpers/users_helper_test.rb invoke jbuilder exist app/views/users create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/users.js.coffee invoke scss create app/assets/stylesheets/users.css.scss 2. μȂʖĊҷк̫̽ĉŪěʬľ ʠɮÞɕDžƻήЬˬěȸ¼ĩɮŎɕDžƻĭʶɮ User ήɮ Users 40 ͩ 2 ͥ ˲͈͘Ʈ invoke scss create app/assets/stylesheets/scaffolds.css.scss ҷR̀ ̫ĚSʑ5 name:string ě email:stringїʠǻUƊþTų̓Šij 2.2 ȁ̛͈̫Ȁʬľ5 ˕DZˎǐϬȦŲ idRails _ο̵ƶƫƃ˜І$ϥ̫%Ҏprimary key ȷʌǻUϬ̛ RakeìϮɡ˕ 2.1ʌю͗migrateɕȰƯ $ bundle exec rake db:migrate == CreateUsers: migrating ==================================================== -- create_table(:users) -> 0.0017s == CreateUsers: migrated (0.0018s) =========================================== ҷ̫ĚS_n̛ɞŲ)̫ User ɕȰʬľɹɞɕȰƯĴ 6.1.1 ω ƃГΎKΑɕȰƯю͗˕DZ$5n̛ Gemfile ȦŲ̫ Rake ̂ʄǻUѫѐ bundle exec ʌȆϡ rakeŠʔln̛ RVMŠÀ ͥȁЗþT Ê bundle execc$5ĚSŰɗǻ_ ̶ѹÊÊ bundle exec іɽ˜PÈ˓ìϮ 3.6.1 ω ˼ĊǻUþTn̛ rails srails server ̫΢̣DžƻʌđÌʄĵɿËĩ $ rails s ̓Ĵ˲͈͘ƮưВƝΒþTѫѐ http://localhost:3000/ ʙ̺5 Íå 2.1Rake Ĵ Unix Ĵƃˬ̀ΠЌǺþȆϡ͘Ʈ̫ѐ͘ make ΍Vг5NjѿϬ̫k̛NjŐ͘Ʈĕ̫сg̙πƝΒ žҷ̫R̀C̚5ʋVñƂ $ ./configure && make && sudo make install їϡR̀Ĵ Unix ÓȠ Linux ě Mac OS X_žR̀јϡΠЌ Rake Ɗɮ Ruby ̫̂ make̛ Ruby Π¢̫Ͷ make ͘ƮRails ˶˘̫ѓ̛5 Rake ̫Éῐºɮȼp5 A̛ʌƷòŃ:ɕȰƯ̫ Web ͘ƮȁҲ̫XËrake db:migrate ɮɼƤ̛̫5іɽNj՘P̫ĚS lþTѓϡ rake -T db ʌʙ̺ȁɽěɕȰƯɽ–̫XË $ bundle exec rake -T db ŠʔϬʙ̺ȁɽ̫ Rake XËѓϡ $ bundle exec rake -T 41 X˲ϥ̺гʌɽ˸ϽGɃ̽Řλѐ̓ĴɣҲȘǏlҲϬ̾ѱȁɽ̫ǼœŐɕĚSŭŰʄɓ ͘Ċl_̾ѱȁɽѿϬ̫ĚS ij 2.4 Users Ьˬ̫¶ţ΂Ƽҹҷ/users 2.2.1 çĴö®þ:ûŲű Їҕʢĵĸ http://localhost:3000/ nj»̫іɮŠij 1.3 ȁ͈̫ Rails ͘Ʈәϻҹҷѐn̛μȂʖ̚Ǻ Users Ьˬ̫ ɩ|0̚Ǻ5NjƠ̋ʌƠ̄̕Ȁ̫ҹҷoŠ²¬ȁɽ̛Ȁ̫ҹҷĵĸɮ /usersµƶɞ̛Ȁ̫ĵĸɮ /users/ newʄω̴̫̫ƊɮбӋϯϊ̫˝ϲ їA̛Ȁ̷–̫ҹҷ˝ϲ̫ɩ|l_ò̓ϥʣ 2.1 Njɽ̛ϥ ɯ͈5 ҹҷě URL ĵĸ*Җ̫žư–΀ ǻUʌ̺ ɯ͈ȁɽ̛Ȁ̫ҹҷý‚“index”Šlȁǯ̴Àіˎɽ̛ȀūĴŠij 2.4 Šʔǯµƶɞ̛ȀƊϬЇҕ“new”ҹҷŠij 2.5 ȁ͈ĴʄĵƷòɩĵĸ̫ÀҷѸ¯ѹɮ http://localhost:3000ĭʶĴĊҷ̫Ź ǻ_̹̣ї Ѹ¯Ĵͩͥ ǻU_ƃ˜ɌѭǺ̛Ȁ˕žҹҷ ϥʣ 2.1 Users Ьˬ ҹҷě URL ̫žư–΀ 42 URL ÌkAction ̴̫ /users index ɯ͈ȁɽ̛Ȁ̫ҹҷ /users/1 show ɯ͈ ID $ 1 ̛̫Ȁ̫ҹҷ /users/new new µƶɞ̛Ȁ̫ҹҷ /users/1/edit edit Πщ ID $ 1 ̛̫Ȁ̫ҹҷ ͩ 2 ͥ ˲͈͘Ʈ ij 2.5 µƶɞ̛Ȁ̫ҹҷ/users/new lþTĴϥʣ ņ‘ĉŪě Email ĵĸ˼Ċ˸­µƶ̛ȀCreate Userȧ҄ʌµƶ ̛Ȁ˼ĊƊ_ɯ͈ї ̛Ȁ̫ҹҷshowŠij 2.6 ȁ͈ҹҷ ̫ΝχɘŪɮѫѐ Flash ˟Ǡų̫̓_Ĵ 7.4.2 ω KΑ˕DZ ҹҷ̫ĵĸɮ /users/1ʵŠl̎ǯ̫їѾ̫ 1 Ɗɮij 2.2 ̛̫Ȁ idĴ 7.1 ω _ƃ˜ȄѭǺ̛Ȁ̫Ьəҹ ҷ ŠʔϬyɌ̛Ȁ̫xǠƊϬЇҕΠщeditҹҷ5Šij 2.7yɌ̛Ȁ̫xǠĊ˸­“ɹɞ̛ȀUpdate User”ȧ҄ƊɹɌ5˲͈͘Ʈ В̛Ȁ̫xǠŠij 2.8Ĵͩ 6 ͥǻU_̺»̛Ȁ̫ɕȰū‡ĴĊ̫ͦɕ ȰƯ ǻU_Ĵ 9.1 ω ˦ÊΠщěɹɞ̛Ȁ̫Éι 43 ij 2.6 ɯ͈ʗ̛Ȁ̫ҹҷ/users/1 ̓ĴǻUѿɞĬ»µƶɞ̛Ȁҹҷ˼ĊȼBϥʣµƶͩ9̛Ȁ˼ĊЇҕ̛Ȁ΂ƼindexҹҷŠij 2.97.1 ωƃΨÔ їɯ͈ȁɽ̛Ȁ̫ҹҷ ǻUƝΒ˲͈5µƶƒ͈Πщ̛Ȁ̫ҹҷҷϬ˲͈҉ʽ̛Ȁҹҷ5Šij 2.10˸­ij 2.10 ̫҈ȷ_ ¬̓ ӎЈžЏʤ͆ϻĊƊ_·Ҧͩ9̛Ȁ΂ƼҹҷƊü_ɯ͈ ̛ȀŠʔїɈkˎɽҼ¹Ű ǺИ͆w˝ϲĩđ̛5 JavaScript Ɋȥ҉ʽ̛Ȁɩ Rails ɮѫѐ JavaScript òѡИˇ̫9.4 ω_ňǁ̛Ȁ̫· ҦÉιüɽͰ̕ĕΈº̛̫Ȁȃι·Ҧ̛Ȁ 2.2.2 MVC ‡Ō ǻUƝΒœʫ̫˝ϲ5 Users ЬˬҷǻUϬ̛ 1.2.6 ω KΑ̫ MVC ̫ϱϴʌOΎ̫̺ ˜ ʗĂŲ̫Ѹ ¯ǻU_¯ʑĴ˝ϲĩ ‚ ʭ˸­̫Ĵѐ͘їѾѫѐЇҕ̛Ȁ΂Ƽҹҷ‚˲͈ʌ5ϵ  MVCŠ ij 2.11 1. ˝ϲĩċ /users òг Иˇ 2. Rails ̫м̜ƃ /user ¯Ѻ» Users ȸ¼ĩ̫ index Ìk 3. index Ìkċ User ʬľϓóȁɽ̛̫ȀUser.all 4. User ʬľMɕȰƯ ƃȁɽ̛̫ȀЙó¬ʌ 5. User ʬľƃȁɽ̛̫ȀѕĬΖȸ¼ĩ 6. ȸ¼ĩƃϓnj̫ȁɽ̛ȀɕȰЭ6 @users õҀ˼Ċ`ѨΖ index ̫ϱij 44 ͩ 2 ͥ ˲͈͘Ʈ 7. ϱijn̛Ɩ Ruby R̫̀ʬʎ˪ʘǺ HTML 8. ȸ¼ĩƃ̚Ǻ̫ HTML òѡĬ˝ϲĩ3 ӊǻUϬM˝ϲĩ òг ИˇlþT̶ȷĴ˝ϲĩĵĸʞ ɖ‘ĵĸ0þT˸­ҹҷ ̫҈ȷij 2.11 ̫ͩ 1 ʷȷ̽Иˇ»э Rails м̜ͩ 2 ʷʢȰ URL ƃ˜¯ò»Ѣǃ̫ȸ¼ĩÌkήі_άҀИ ˇ̫Ͷľɡ˕ 3.2 _KΑƃ Users Ьˬ ̷–̫ URL ɭƂ»ȸ¼ĩÌk̫R̀ŠR̀ 2.2 ȁ͈їAR̀ _ȧ˽ϥʣ 2.1 ̫žư–΀‚ɭƂ:users ɮ  Symbol4.3.3 ω_KΑ R̀ 2.2 Rails ̫м̜ІΦÓď ʋ Users Ьˬ̫ϰ³ config/routes.rb DemoApp::Application.routes.draw do resources :users . . . end ij 2.7 Πщ̛Ȁ̫ҹҷ/users/1/edit 3. ɽAɘͥ_Зɮϱij̶ȷƃ HTML ѕĬΖ˝ϲĩ̫ѫѐ Web ɿËĩoŠ Apache ě NginxͰų̫̓Ύωɮǚʠ̫ ǻɹ̷xȸ¼ĩɮ  ʕư̛͘Ʈ ȁɽ̫xǠѹ_ѫѐŮ 45 2.2.1 ω ˝ϲ̫ҹҷƊžư5 Users ȸ¼ĩ Ĉ̫ÌkμȂʖ̚Ǻ̫ȸ¼ĩR̀œρŠR̀ 2.3 ȁ͈˕DZ  class UsersController < ApplicationController ̛̫˓їɮ Ruby ͶΚȍ̫¢˓2.3.4 ω ƃͮϬ̫KΑ Κȍ4.4 ωƃГΎKΑͶěΚȍ R̀ 2.3 ̛Ȁȸ¼ĩ̫R̀ʫϬ app/controllers/users_controller.rb class UsersController < ApplicationController . . . def index . . . end def show . . . end def new . . . end def create . . . end def edit . . . end def update . . . end 46 def destroy . . . end end ͩ 2 ͥ ˲͈͘Ʈ ij 2.8 ɯ͈“xǠƝɹɞ”ȼ̛͈̫Ȁҹҷ ǼЄlò̓5Ìk̫ɕҀˀǻU̺ѐ̫ҹҷɕҀϬŐindexshownew ě edit žư5 2.2.1 ω KΑ̫ҹ ҷѐіɽ A˜P̫Ìkcreateupdate ě destroy ͪїAÌk υ_̶ȷ˪ʘҹҷѐɽɩ0 _ŮUü_yɌɕȰƯ wư̫̄ȀɕȰϥʣ 2.2 ²¬̫ɮȸ¼ĩ̫’ѸÌkїAÌkƊɮ Rails ž REST ʖʐìϮɡ˕ 2.2̫ų̓REST ɮ̜Ϲͯʆ͒ŭŸ Roy Fielding ȼ¬̫ʫǖDZǜɮϥ̓Ə̉ǙтÔ Representational State Transfer4 ˕DZϥʣ 2.2 ̫ŹɽAѸ¯ɮɽѿ÷̫oŠ show ě update Ì kѹɭƂ» /users/1 їĵĸ9έ̫׺ɮŮUȁ̛̫ HTTP Иˇɟ˓Ĉ3.2.1 ωƃɹГΎ̫KΑ HTTP И ˇɟ˓ 4. ʹ͍Ƌ@œŭʰɘ¯ʟ 2000 ƪ Roy Thomas Fielding ̫àʼnЅɘʖʐӈʣŃ:ΤΗ̫фVʖʐІϹЌέ˕ Ќ ɘΪ 47 Íå 2.2ĮóŽð©ŎOREST ŠʔlҘЙѐ A Ruby on Rails Web Ʒò̷–̫Ьəl_̺»NjŐĵɟѹȼ»5“REST”Ůɮ“ϥ̓Ə̉Ǚ тÔREpresentational State Transfer”̫͖ͮREST ɮ ͑ʖʐɟƻ̛ʌƷò¯ƞƻŃ:ΤΗ̫΀Ιě ͘ƮoŠ WWW ě Web ư̛͘ƮREST ̕ЅɮNjȗП̫Ĵ Rails ͘Ʈ REST DZĘ̽œŐɕ̫΍V oŠ̛Ȁěǎà_ϧʬľÔõǺЬˬresourceþTϧµƶcreateЙóreadɹɞ updateě·ҦdeleteїAɈk_–΀ľɕȰƯ ̫ CRUD Ɉkě HTTP Иˇɟ˓POSTGET PATCH ě DELETEžưгʌ3.2.1 ω̆ºɮɡ˕ 3.3ƃɹГΎ̫KΑ HTTP Иˇ k$ Rails ͘ƮƷòέREST Ʒòɟƻ_ƣÍl¤ŲΠ¢ĠAȸ¼ĩěÌk lüҲͮÞ̫ƃþTµƶЙ óɹɞě·Ҧ̫Ьˬ̕˧ƊþT5žʄ̛̫ͥȀěǎàʌЗї ѐ͘ҵƤɪ͆ĭ$ŮUѹɮNjο˼̫ ЬˬDžƻĴͩ 11 ͥ ƃ̺» REST ʖʐŠЄǻUƃ NjʩȂ̫ҕӄ“–˕̛Ȁ”Éιѫѐ ͑ο˼ήt ȱ̫ɟƻŌ̕ ij 2.9 ɯ͈5ͩ9̛Ȁ̛̫Ȁ΂Ƽҹҷ/users 48 ͩ 2 ͥ ˲͈͘Ʈ ij 2.10 ҉ʽ̛Ȁ ϥʣ 2.2 R̀ 2.2 Users Ьˬ̚Ǻ̫ͨć REST ʖʐ̫м̜ HTTP Иˇ URL Ìk ̴̫ GET /users index ɯ͈ȁ̛̛Ȁ̫ҹҷ GET /users/1 show ɯ͈ ID $ 1 ̛̫Ȁҹҷ GET /users/new new µƶɞ̛Ȁ̫ҹҷ POST /users create µƶɞ̛Ȁ GET /users/1/edit edit Πщ ID $ 1 ̛̫Ȁҹҷ PATCH /users/1 update ɹɞ ID $ 1 ̛̫Ȁ DELETE /users/1 destroy ·Ҧ ID $ 1 ̛̫Ȁ 49 ij 2.11 Rails MVC ̫ГΎЗɪijϵ $5ϵѽ Users ȸ¼ĩě User ʬľ*Җ̫–΀ǻUϬ̺ ͮÔ5̫ index Ìk̫R̀ŠR̀ 2.4 ȁ͈μ Ȃʖ̚Ǻ̫R̀Nj͸;ȁTǻU‚5ͮÔ R̀ 2.4 ˲͈͘Ʈ ϧͮÔ5̛̫Ȁ index Ìk app/controllers/users_controller.rb class UsersController < ApplicationController . . . def index @users = User.all end . . . end index Ìkɽ ϡR̀ɮ @users = User.allij 2.11 ̫ͩ 3 ʷŮϬˇ User ʬľMɕȰƯ ó¬ȁɽ̫ ̛Ȁͩ 4 ʷ˼ĊƃΔʔЭ~Ζ @users õҀͩ 5 ʷUser ʬľ̫R̀ìϮR̀ 2.5R̺̀bͮÞ ѐŮѫѐΚȍ™ō5NjŐÉιìϮ 2.3.4 ω ě 4.4 ωͮÞʌЗƊɮѫѐЛ̛ Rails ý‚ Active Record ̫Ư R̀ 2.5 ̫ User.all Ɗ_ѕĬȁɽ̛̫Ȁ 50 ͩ 2 ͥ ˲͈͘Ʈ R̀ 2.5 ˲͈͘Ʈ ̫ User ʬľ app/models/user.rb class User < ActiveRecord::Base end ɦŲ)5 @users õҀȸ¼ĩƊ_Л̛ϱijR̀ͩ 6 ʷ˜R̀ŠR̀ 2.6 ȁ͈T @ ƷŘ̫õҀɮ“ųo õҀinstance variable”Ĵϱij οÌþ̛Ĵʄo index.html.erb ϱij̫R̀_Ѱè @users$ʿ ̛Ȁ̚Ǻ ϡ HTMLЁfl̓ĴþιЙǷїAR̀їѾüɮϽl̺ їAR̀ɮH(ʠũ R̀ 2.6 ̛Ȁ΂Ƽҹҷ̫ϱijR̀ app/views/users/index.html.erb

Listing users

<% @users.each do |user| %> <% end %>
Name Email
<%= user.name %> <%= user.email %> <%= link_to 'Show', user %> <%= link_to 'Edit', edit_user_path(user) %> <%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %>

<%= link_to 'New User', new_user_path %> ϱij_ƃR̀тȮǺ HTMLͩ 7 ʷ˼Ċȸ¼ĩƃ˜ѕĬ˝ϲĩɯ͈¬ʌͩ 8 ʷ 2.2.3 ŕ Users ʼnìûğŭ μȂʖ̚Ǻ̫ Users Ьˬ̷–R̀ϝ˼ιŒϽlœρ̫5ϵ  RailsѐŮ0ɽ AΣҨ • ˎɽžɕȰјϡӎЈvalidationUser ʬľ_ȷô̫͝ĉŪěć˓̫ Email ĵĸή_ȔҌ 51 • ˎɽ̛ȀсYӎЈʆ¼authenticationˎɽų̨̓DŽěѠ¬ÉιҩDZ ̛ȀѹþTјϡXh̫Ɉ k • ˎɽ˜Ѝ0ɮےˎɽμȂʖ_̚Ǻ AŃʄ̫˜ЍѐNj͸;0˶tˎɽžɕȰјϡӎ ЈÓďӎЈʆ¼̫˜ЍTî˜P̫Ҳˇ • ˎɽƞƎˎɽ•̛̫ʠƻěΤͤƀτ • ˎɽ̻ʵ̫ϧ̕ϵŠʔlιЙǷμȂʖ̚Ǻ̫R̀ƊҲϬҘЙʄ25 2.3 Microposts ʼnì ǻUƝΒ̚Ǻ0˝ϲ5 User Ьˬ̓ĴϬ̚Ǻ Microposts Ьˬ5ҘЙʄωɩǻȹϐlě 2.2 ωžˀ l_̺ »ЬˬĴNjŐɟҷѹɮ ρ̫ѫѐїʠѿŎ̫̚ǺЬˬǻUþTɹş̫̕ϵ Rails ̫ REST ʖʐĴїʠ ̫ɨʁҜʼ̺  Users Ьˬě Microposts Ьˬ̷̫Ĉ*Ō0ɮʄ̫ͥ%Ϭ̴̫* ĊҷǻU_̺»Ʒò ˀʄ̫ͥ˲͈͘ƮŎʇ̫͘ƮϬQ¬NjŐˈ˅Microposts ЬˬĴͩ 10 ͥȃ_̛»ήǻǯї(ɰȃKΑ 2.3.1 ßĴ Microposts ʼnì ě Users Ьˬ ʠǻUn̛ rails generate scaffold ĚS̚Ǻ Microposts Ьˬ̫R̀ų̓ij 2.3 ȁ͈ ̫ɕȰʬľ 5 $ rails generate scaffold Micropost content:string user_id:integer invoke active_record create db/migrate/20130307005528_create_microposts.rb create app/models/micropost.rb invoke test_unit create test/models/micropost_test.rb create test/fixtures/microposts.yml invoke resource_route route resources :microposts invoke jbuilder_scaffold_controller create app/controllers/microposts_controller.rb invoke erb create app/views/microposts create app/views/microposts/index.html.erb create app/views/microposts/edit.html.erb create app/views/microposts/show.html.erb create app/views/microposts/new.html.erb create app/views/microposts/_form.html.erb invoke test_unit create test/controllers/microposts_controller_test.rb invoke helper create app/helpers/microposts_helper.rb 5. ě̚Ǻ Users Ьˬ̫μȂʖĚS ʠ̚Ǻ Microposts Ьˬ̫μȂʖ0n̛5ÞɕDžƻĭʶǻUn̛ generate Micropost 52 ͩ 2 ͥ ˲͈͘Ʈ invoke create invoke exist create create invoke invoke create invoke create invoke identical test_unit test/helpers/microposts_helper_test.rb jbuilder app/views/microposts app/views/microposts/index.json.jbuilder app/views/microposts/show.json.jbuilder assets coffee app/assets/javascripts/microposts.js.coffee scss app/assets/stylesheets/microposts.css.scss scss app/assets/stylesheets/scaffolds.css.scss ˼ĊϬɹɞɕȰƯn̛ɼɞ̫ɕȰʬľǻUϬȆϡͶb 2.2 ω ̛»̫ю͗ĚS $ bundle exec rake db:migrate == CreateMicroposts: migrating =============================================== -- create_table(:microposts) -> 0.0023s == CreateMicroposts: migrated (0.0026s) ====================================== ̓ĴǻUƊþTn̛Ͷb 2.2.1 ω KΑ̫ɟ˓ʌµƶǎà5Ɗˆl̎˜̫μȂʖ0_ɹɞ Rails ̫м̜ɘV $ Microposts Ьˬʑ ʋϰ³ŠR̀ 2.7 ȁ͈6 ě Users Ьˬ ʠresources :micropsts _ƃǎà̷– ̫ URL ĵĸɭƂ» Microposts ȸ¼ĩŠϥʣ 2.3 ȁ͈ ϥʣ 2.3 R̀ 2.7 Microposts Ьˬ̚Ǻ̫ͨć REST ʖʐ̫м̜ HTTP Иˇ URL Ìk ̴̫ GET /microposts index ɯ͈ȁɽǎà̫ҹҷ GET /microposts/1 show ɯ͈ ID $ 1 ̫ǎàҹҷ GET /microposts/new new ɯ͈µƶɞǎà̫ҹҷ POST /microposts create µƶɞǎà GET /microposts/1/edit edit Πщ ID $ 1 ̫ǎàҹҷ PATCH /microposts/1 update ɹɞ ID $ 1 ̫ǎà DELETE /microposts/1 destroy ·Ҧ ID $ 1 ̫ǎà R̀ 2.7 Rails ̫м̜ѺΦɽ ʋ҂ž Microposts Ьˬ̫ɞϰ³ config/routes.rb 6. ěR̀ 2.7 ̷ˀμȂʖ̚Ǻ̫R̀þι_ɽӆŏ̫͝ϡlɣҽȘǏĭ$ Ruby _Ụ̈́ӆŏ̫͝ϡ 53 DemoApp::Application.routes.draw do resources :microposts resources :users . . . end Microposts ȸ¼ĩ̫R̀ͮÔĊŠR̀ 2.8 ȁ͈˕DZҦ5ƃ UsersController ȮǺ MicropostsController *ŏїʼR̀ěR̀ 2.3 ˎH(׺їЗɪ5їЬˬĴ REST ʖʐ ̫•Ĉ* Ō R̀ 2.8 Microposts ȸ¼ĩ̫R̀ͮÔDžƻ app/controllers/microposts_controller.rb class MicropostsController < ApplicationController . . . def index . . . end def show . . . end def new . . . end def create . . . end def edit . . 54 . end def update . . . end def destroy . . . end end ǻUĴµƶǎàҹҷ/microposts/newъ‘ AŹʌ˦Ê ǎàŠij 2.12 ȁ͈ ͩ 2 ͥ ˲͈͘Ʈ ij 2.12 µƶǎà̫ҹҷ/microposts/new ɤ˼ƝΒĴїҹҷ5ѶƊŐµƶ©ǎà͆wπƅɽ ǎà̫ user_id І$5 1їʠƊžư» 2.2.1 ω µƶ̫ͩ ̛Ȁ5ΔʔưВěij 2.13 Ͷb 55 2.3.2 ūI¦S=ˆûŨ ŠʔϬ͖njǎàїʠ̫ĉŪƊϬҤ¼˜Ź̫ґƴĴ Rails ų̓ї͑Ҥ¼NjͮÞn̛ɕȰӎЈ validationÉιϬҤ¼ǎà̫ґƴɼœ$ 140 ŪͨƊˆ Twitter ʠǻUþTn̛ґƴҤ¼ɕȰӎЈ ̓ĴlþT̛l̫ɘʄΠщĩǼ IDE ȄƷ app/models/micropost.rb ¢‘R̀ 2.9 ȁ͈̫R̀R̀ 2.9 n̛̫ validates ɟ˓ü҂ž Rails 3 Šʔl*À̛ѐ Rails 2.3ƊþTžˀ Ůě validates_length_of ̫׺ ij 2.13 ǎà΂Ƽҹҷ/microposts R̀ 2.9 ̓Ĵǎà̫ґƴɼґ$ 140 Ūͨ app/models/micropost.rb class Micropost < ActiveRecord::Base validates :content, length: { maximum: 140 } end ҷ̫R̺̀гʌþιNj͔͋ǻU_Ĵ 6.2 ω ГΎKΑɕȰӎЈŠʔǻUĴµƶǎàҹҷъ‘дѐ 140 Ū ̫ͨŹƊ_̺»їӎЈ̫ʠũ5Šij 2.14 ȁ͈Rails _ɯ͈ ҌЕȼ͈xǠerror messageȼ͈ǎà̫ Źŕґ57.3.3 ωƃɹГΎ̫KΑҌЕxǠ 56 ͩ 2 ͥ ˲͈͘Ʈ 2.3.3 ö®ÒzϦS Rails ǁœ̫Éι* ɮþT$Ĉ̫ɕȰʬľ*Җµƶ–γassociation҂žʄo ̫ User ʬľʿ̛Ȁþ TɽŐͳǎàǻUþTѫѐɹɞ User ʬľìϮR̀ 2.10ě Micropost ʬľìϮR̀ 2.11̫R̀ʌų̓ї ͑–γ ij 2.14 µƶǎàŗХĊɯ͈̫ҌЕxǠ R̀ 2.10 ̛ȀɽŐͳǎà app/models/user.rb class User < ActiveRecord::Base has_many :microposts end R̀ 2.11 ͳǎàüƓ: ̛Ȁ app/models/micropost.rb class Micropost < ActiveRecord::Base belongs_to :user validates :content, length: { maximum: 140 } end 57 ǻUþTƃї͑–γ̛ij 2.15 ȁ͈̫ijDžϥ͈¬ʌĭ$ microposts ϥ ɽ user_id ї ²ȁT Railsѫ ѐ Active RecordƊþTƃǎàěʿ̛Ȁ–γгʌ ij 2.15 ǎàě̛Ȁ*Җ̫–γ Ĵͩ 10 ͥěͩ 11 ͥ ǻUƃn̛̛Ȁěǎà*Җ̫–γʌɯ͈ʗ ̛Ȁ̫ȁɽǎàƫ̚Ǻ ě Twitter Ͷb̫ÌǙ²ϥǻUþTn̛ȸ¼ÿconsoleʌʨʙ ̛Ȁǎà*Җ–γ̫ų̓ȸ¼ÿɮě Rails ư̛ ͘ƮB=Njɽ̛̫Ƙ™ĴĚSϡ Ȇϡ rails console ʌđÌȸ¼ÿ˼Ċn̛ User.first MɕȰƯ Й óͩ ̛ȀƫƃЙó̫ɕȰЭ~Ζ first_user õҀ 7 $ rails console >> first_user = User.first => # >> first_user.microposts => [#, #] >> exit ҷR̀ ǻÓď5ɼĊ ϡ̛ʌ˲͈ŠhѠ¬ȸ¼ÿĴœŐɕ΀Ι 0þTn̛ Ctrl-d ΍ćҎ˼Ċn̛ first_user.microposts ϓớȀ̫ǎà Active Record _οÌѕĬ user_id ě first_user ̫ id ̷Ĉ̫ 1ȁɽǎàǻUƃĴͩ 10 ͥěͩ 11 ͥɹГΎ̫ŭ1 Active Record ї͑–γ̫ų̓ 2.3.4 ě´:đ ȷʌǻUɵɩΔʉ˲͈͘Ʈ̫ϼЅʌͮÞ̫KΑ  Rails ȸ¼ĩěʬľ̫ͶΚȍŠʔlɽ AҷċžП Π͘Object-oriented ProgrammingOOP̫Βӎƃɹş̫̕ϵїAŹŠʔlʂȷ϶ѐ OOP̫ЏþTѥȟнѐ ʄƄω υʌЗŠʔl˾ǣͶ̫ʫǖ4.4 ω _KΑǻƶϿl͙ɰAɩ|ŸĬѐŘʌ̺ʄƄω ǻUKΑʬľ̫Κȍ–΀žˀ R̀ 2.12 ěR̀ 2.13 ̫R̀User ʬľě Micropost ʬľѹΚȍοѫѐ <ActiveRecord::BaseŮɮ ActiveRecord $ʬľȼp̫ŃͶij 2.16 ²¬5ї͑Κȍ–΀ѫѐΚȍ ActiveRecord::Base ǻU̫ʬľžПȃιŒěɕȰƯѫЀƃɕȰƯ ̫²̺‚ Ruby ̫Ɠǝͪ R̀ 2.12 User ͶÓȠΚȍ–΀ app/models/user.rb 7. l̫ȸ¼ÿþι_ɯ͈Ͷb ruby-2.0.0-head > ̫ƷŘ͈o n̛ >> ɻRĭ$Ĉ̫ Ruby ̂ʄ_ɽȁĈ 58 class User < ActiveRecord::Base . . . end R̀ 2.13 Micropost ͶÓȠΚȍ–΀ app/models/micropost.rb class Micropost < ActiveRecord::Base . . . end ͩ 2 ͥ ˲͈͘Ʈ ij 2.16 User ʬľě Micropost ʬľ̫Κȍ–΀ ȸ¼ĩ̫Κȍ–΀ɹŎʇ Ažˀ R̀ 2.14 ěR̀ 2.15ǻUþT̺» Users ȸ¼ĩě Microposts ȸ¼ĩѹ Κȍοư̛͘Ʈ̫ȸ¼ĩApplicationControllerŠR̀ 2.16 ȁ͈ApplicationController Κȍ ο ActionController::BaseŮɮ Rails ̫ Action Pack Ư$ȸ¼ĩȼp̫ŃͶїAͶ*Җ̫–΀Šij 2.17 ȁ͈ ij 2.17 Users ȸ¼ĩě Microposts ȸ¼ĩ̫Κȍ–΀ R̀ 2.14 UsersController ͶÓďΚȍ–΀ app/controllers/users_controller.rb 59 class UsersController < ApplicationController . . . end R̀ 2.15 MicropostsController ͶÓďΚȍ–΀ app/controllers/microposts_controller.rb class MicropostsController < ApplicationController . . . end R̀ 2.16 ApplicationController ͶÓďΚȍ–΀ app/controllers/application_controller.rb class ApplicationController < ActionController::Base . . . end ěʬľ̫ΚȍͶbѫѐΚȍ ActionController::BaseUsers ȸ¼ĩě Microposts ȸ¼ĩϓnj5NjŐ̫É ιoŠŌ̕ʬľžП̫Éιѐ˰ъ‘̫ HTTP ИˇTîƃϱij˪ʘǺ HTML ̫Éιĭ$ Rails ̫ȸ¼ĩ ѹΚȍο ApplicationControllerȁTĴư̛͘Ʈȸ¼ĩ Ų)̫ŹƊ_ư̛»͘Ʈ ̫ȁɽÌko ŠĴ 8.2.1 ω ƃ̺»ŠhĴư̛͘Ʈȸ¼ĩ ˦Ê ̨DŽѠ¬̫ƣÍɟ˓ 2.3.5 ŞĢíāą› ŰǺ Microposts Ьˬ*Ċɮɩ|ƃR̀ȹѡ» GitHub ̫NƯ 5 $ git add . $ git commit -m "Finish demo app" $ git push ѫƤǧ¥lưВΒƤ‚ ANjƄ̫ȼBѐž:ʄͥʌЗɼĊ‚ ʭœ̫ȼB0þT ˼Ċl0þTȧ˽ 1.4 ω KΑ̫ɟ˓ƃ˲͈͘ƮѸΧ» Herokužї˲͈͘ƮʌЗҲϬІΦ RailsϽ˜ι ŒɿË:ҴǙЬˬɘVoŠij́ěʠƻϥ̷–̫ІΦһ̴әϻɮ–Ҕ̫ĭ$NjŐ Web ɿËĩþTοÌų̓ї ÉιϬyɌәϻ̫ІΦǻUϬΠщ config/environments ɘVř ̫ production.rb ɘVŠR̀ 2.17 ȁ͈ R̀ 2.17 ІΦ RailsϽ˜Ĵ̚C̒Ň ɿË:ҴǙЬˬɘV config/environments/production.rb 60 ͩ 2 ͥ ˲͈͘Ʈ DemoApp::Application.configure do . . . config.serve_static_assets = true . . . end ‚ş5ѝyɌĊƊþTȏ͘Ʈȹѡ» Heroku 5 $ git commit -a -m "Serve static assets" $ heroku create $ git push heroku master ɼĊю͗̚C̒Ň ̫ɕȰƯŠʔnj»ҌЕȼ͈Иìάҷ̫Ź $ heroku run rake db:migrate ҷ̫R̀_̛ User ě Micropost ɕȰʬľɹɞ Heroku ̫ɕȰƯŠʔnj» vendor/plugins Ьˬ asset̷–̫ҌЕȼ͈ɵỤ̈́Ůĭ$ǻUіˎn̛ȽV 2.4 ŒĘ ̓ĴǻUƝΒΔʉ5ž  Rails ư̛͘Ʈ̫¯ʑʄͥ Ʒò̫˲͈͘Ʈɽ Aş̫ĵɟ0ɽ AɽΣҨ̫ĵ ɟ ûpÌ • ʫϲ5 Rails • KΑ5 MVC • ͩ ʭgӎ5 REST ʖʐ • Ʒţn̛ɕȰʬľ5 • Ĵ̚C̒Ň ѓϡ5 Ń:ɕȰƯ̫ Web ͘Ʈ ÒğŭûpÌ • ˎɽοŲ)ƞƎěʠƻ • ˎɽҴǙҹҷoŠ“ӊҹ”ě“–:” • ˎɽ̛Ȁź̀ • ˎɽ̛Ȁ؈ • ˎ̨DŽÉι • ů’ 61 • ˎų̛̓Ȁěǎà̫οÌ–γ • ˎų̓“–˕”ě“ϧ–˕”Éι • ˎų̓ÌǙ²ϥ • ˎn̛ TDD • ˎɽ̻̫̕ϵȁ‚̫8ǧ ʄ2ĊΛ̫Ź_ƶ͢ĴїAş̫Ѹ¯*˼ĊɌĦɽΣҨ̫Ѹ¯ 62 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ĉ 3 ć uÓŰ©ûŲű MʄͥƷţǻUϬƷò œľ̫͈o͘Ʈʄ2Ċ˝Źѹ_Ń:ї͈o͘ƮɼΐŰǺ̫͘Ʈ_Óď̛Ȁ ǎàÉιTîŰɗ̨̫DŽě̛ȀсYӎЈ΀ΙѐǻU_M ̺bÉιɽҤ̫Џӄ¬ò——µƶҴǙҹҷ ї̺bͮÞ̫ V8æɮ Njş̫ҏ˹ʏ™DZ)žї¶ƶ̫͘ƮήϷ0ɮNjş̫Ʒͦ ϝ˼ Rails ɮϧІϹ̛ʌƷòŃ:ɕȰƯ̫ÌǙΤ̫ͤѐŮ0ιθXn̛Ή HTML µƶ̫ҴǙҹҷ˜ųn ̛ Rails µƶÌǙҹҷіɽ ˸şŌ ǻUþTɟt̫˦Ê ƄѸ¯ÌǙŹї ͥƊ_ɓlǚ(‚Ĵїѐ ͘ ǻUі_ ͡οÌÔ˜Ѝautomated testing̫ҷ̴οÌÔ˜ЍþTϽǻU͆xοƜΠ¢̫R̀ɮʵ̫͆ ήΠ¢ ş̫˜Ѝ̛oіþTϽǻUxǏÙз̫ѿʐrefactorR̀yɌų̓ѐ͘cdžĞɼΐɐʔ ʄͥɽNjŐ̫R̀̆ºɮĴ 3.2 ωě3.3 ωŠʔlɮ Ruby ¶ŭݍ̛ȘǏˎɽ̕ϵїAR̀ƊˆĴ 1.1.1 ω Зѐ̫lþT̶ȷŎ¼͹Ъ˜ЍR̛̀ʌӎЈ͘Ʈ R̫̀ʵ͆ǝή̛ȘǏ˜Ƙkêͩ̕ 4 ͥ_ɹГΎ ̫KΑ Rubylɽ̫ɮʆ_ʌ̕ϵїAR̀іɽ RSpec ˜ЍŮĴʄ2 _ϧñŎn̛Šʔl̓Ĵɽ˸âf 5ǻƶϿl̽ͅŘ̭Lj̺©ͥѐĊlƊ_ǨŚĵò̓êʄ̺гʌNjЫϵ̫R̀ƝΒõnjNjŹɫ̕ϵ5 lіþTάϛŭ1 Code School ̫ RSpec К͘ɽ$ЙέЗїК͘ϵǩ5NjŐ RSpec ̥ҕ Ͷbͩ9ͥĴƷţ*ÀǻUϬµƶ ɞ̫ Rails һ̴їѾǻUýŮ sample_app $ cd ~/rails_projects $ rails new sample_app --skip-test-unit $ cd sample_app ҷR̀ `ѨΖ rails ĚS̫ --skip-test-unit ѥһ̫DZǜɮϽ Rails ̚Ǻәϻn̛̫ Test::Unit ˜ Ѝʤʖžư̫ test ɘVřїʠ‚ƫɮЗǻƯ¢˜ЍήɮM 3.2 ωƷţǻU_n̛û ˜Ѝʤʖ RSpec ʌ¢ɗ̫˜Ѝ̛o Ͷb 2.1 ωȷʌǻUϬ̛ɘʄΠщĩȄƷƫΠщ Gemfile¢‘͘ƮȁҲ̫ gemї͈o͘Ʈ_̛»*Àˎ ̛ѐ̫ gem RSpec ȁҲ̫ gem ě҂ž Rails ̫ RSPec Ư gemR̀ 3.1 ȁ͈̫R̀_ÓďїA gem˕ DZ ŠʔʶɩlǯůϪї͈o͘Ʈ̛»̫ȁɽ gemlưВn̛R̀ 9.48 ̫R̀ R̀ 3.1 ͈o͘Ʈ̫ Gemfile source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' group :development, :test do gem 'sqlite3', '1.3.7' gem 'rspec-rails', '2.13.1' end 63 group :test do gem 'selenium-webdriver', '2.0.0' gem 'capybara', '2.1.0' end gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' gem 'jquery-rails', '2.2.1' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' group :doc do gem 'sdoc', '0.3.20', require: false end group :production do gem 'pg', '0.15.1' end ҷ̫R̀ƃ rspec-rails ɎĴ5Ʒò΍ їʠǻUƊþTn̛ RSpec ̷–̫̚Ǻĩ5ĈʠǻUіȏŮɎ» 5˜Ѝ΍ їʠȃιĴ˜Ѝɩn̛ǻUˎǐϬÞ̫̌ůϪ RSpecĭ$Ůɮ rspec-rails ̫qЯV dependency_ϧοÌůϪǻUіÊ‘5 Capybaraї gem ŠЄǻUn̛ͶbύД ̫ú˓Π¢ʬȝư ̛͘ƮB=̫R̀іɽ Capybara ̫ qЯƯ Selenium1 ěͩ 2 ͥ ʠǻUіϬȏ PostgreSQL ȁҲ̫ gem ʑ̚C΍їʠȃιѸΧ» Heroku group :production do gem 'pg', '0.15.1' end Heroku ȹϐĴƷò̒Ňě̚C̒Ňn̷̛Ĉ̫ɕȰƯѐžǻU̫͈o͘ƮήϷˎH(džĞSQLite ˀ PostgreSQL ɹŹɫůϪěѺΦĴl̫̞λ ůϪěѺΦ PostgreSQL _k$ Ό1ìϮ 3.5 ω ϬůϪěÓďїAɞÊ̫ gemИѓϡ bundle update ě bundle install $ bundle install --without production $ bundle update $ bundle install  1.4.1 ω ěͩ 2 ͥ ʠǻUn̛ -without production ͌ʴůϪ̚C̒ŇȁҲ̫ gemїѥһ_ϧЁ fȁTĊΛЛ̛ Bundler Ɗ̛ŸȦŲїѥһ̶ȷѓϡ bundle install ƊþTοÌůϪ̚C̒ŇȁҲ ̫ gem2 1. Webrat ̫ΚXέCapybara ɮT̠ɼœ̫ĤӜͶÌ̄Ěĉ̫ 64 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ȷ̽ǻUϬІΦ Ͻ Rails n̛ RSpec ή̛ Test::UnitїІΦþTѫѐ rails generate rspec:install ĚSų̓ $ rails generate rspec:install Šʔ΀Ιȼ͈Σƅ JavaScript ѓϡɩlþTЇҕ execjs Ĵ GitHub ̫ҹҷʙ̺þTn̛̫ѓϡɩ ǻ υѹƶϿů Ϫ Node.js ˼ĊÃ̫Ɗɮ¶ţÔ Git NƯ5 3 $ git init $ git add . $ git commit -m "Initial commit" ěͩ ͘Ʈ ʠǻƶϿlɹɞ  README ɘVɹş̫Ȼѝї͘ƮіþTȼp AƣÍxǠþì˽R ̀ 3.2 R̀ 3.2 ͈o͘ƮɌĦĊ̫ README ɘV # Ruby on Rails Tutorial: sample application This is the sample application for the [*Ruby on Rails Tutorial*](http://railstutorial.org/) by [Michael Hartl](http://michaelhartl.com/). ˼Ċ˦Ê .md ĊΞƃ˜ɹɌ$ Markdown ʣƻŸȼBȁ‚̫yɌ $ git mv README.rdoc README.md $ git commit -am "Improve the README" lþιіЁnjĴ 1.3.5 ω ǻUn̛5 git commit -a -m "Message" ĚSȦŲ5“’ѸõÔ”̫ɢʜ -a ěȼBxǠɢʜ -mŠҷͩ9ĚSȁ͈þTȏїɢʜěĴ гn̛ git commit -am "Message" ĚS ї͘ƮĴʄ2̫ĊΛͥω_ ̶n̛ȁTƶϿlĴ GitHub ɞƶ NƯ˼ĊƃR̀ȹѡë $ git remote add origin https://github.com//sample_app.git $ git push -u origin master ǻοƜ0‚5ї ʷlþTĴ GitHub Ȍ»ї͈o͘Ʈ̫R̀ǻ̛5 ͙ǎĈ̫ĉŪ4 ǃ˼ǻU0þTѥȟĴїɨʁҜʼƃ͘ƮѸΧ» Herokuě 2.3.5 ω ʠ8ϬІΦ RailsϽ˜ɿËҴǙЬˬ ɘVŠR̀ 3.3 ȁ͈ 2. 8ųlþT̹̣ installÞ̫̌ bundle Ɗɮ bundle install ̫ºĉ 3. ě*À ʠn̛R̀ 1.7 ̫Źžl̫΀Ιþιɹɽ̛ 4. https://github.com/railstutorial/sample_app_rails_4 65 R̀ 3.3 ІΦ RailsϽ˜ɿËҴǙЬˬɘV config/environments/production.rb SampleApp::Application.configure do . . . config.serve_static_assets = true . . . end ІΦĊƊþTȹѡ» Heroku 5 $ git commit -am "Serve static assets" $ heroku create $ git push heroku master ĴҘЙʄ2̫ѐ͘ ǻƶϿlΒƤĵȹѡƫѸΧї͘Ʈ $ git push $ git push heroku їʠlþĴљͦ‚ōY0þTƌɨ̫ϓ̾̚Ǻ̒Ň ¬̫̓ҌЕŠʔlĴ Heroku ѯ»5ҕӄþT̺  ̚C̒Ň̫ɥǒɘVƉЍϵ¤ $ heroku logs ͆wl‚5R̀ 3.3 ȁ͈̫ІΦ ȁɽ̫¦ōƘkѹΔʉ5ҷϬƷţƷòї͈o͘Ʈ5 3.1 Ű©Ųű ʄωǻUϬċƷòÌǙҹҷё¬ͩ ʷµƶ A Rails ÌkěϱijcüÓďҴǙ HTML[^1-5]Rails ÌkɎĴ ȸ¼ĩMVC ̫ CìϮ 1.2.6 ω ȸ¼ĩ Óď̫Ìkѹɮ$5ų̓Ĉ ͶÉι̫ͩ 2 ͥ ƝΒͮϬKΑ 5ȸ¼ĩǃɹŰɗ̫˾ǣ REST ʖʐĊMͩ 6 ͥƷţ_ɹˤ‘̫͢åȸ¼ĩʄЧȸ¼ĩƊɮ ΍Τҹ þιɮÌǙ̫̫Źĩ ̓ĴĬǯ  1.2.3 ω Ђѐ̫ Rails ̴DŽΔʐij 1.2_žǻUɽ˸ƣÍʄω%Ϭ̫ƘkѹĴ app/ controllers ě app/views ɘVř 3.2 ω ǻUі_ɞƶ ɘVřǻƶϿl̓ĴĴɘʄΠщĩǼ IDE ȄƷ͈o͘ƮìϮɡ˕ 3.1 66 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ Íå 3.1±Ÿųü ĴɘʄΠщĩǼ IDE ȄƷɗ Rails ̴DŽ_ƢʌNjŐt¹ѐǚ(‚æó¤:l̫΀ΙœŐɕǧ¥l þTĴĚSϡ ̛lѥȟ̫˝ϲĩĚSȄƷǃÀư̛͘ƮȁĴ̴̫DŽĴ Unix ǃÀ̴DŽƊɮ ˸Ă . $ cd ~/rails_projects/sample_app $ . oŠ̛ Sublime Text ȄƷ͈o͘ƮlþTъ‘ $ subl . ž: Vim ʌЗъ‘ $ vim . lþTʢȰln̛̫ Vim õ͑ȏ vim ɻȮǺ gvim Ǽ mvim Š 1.3.5 ω ȁЗĴƷţ*ÀŠʔn̛ GitɼşºĴ%¯ɊƷòϬɞƶ M¯ɊŠʔlʵn̛ Git ‚̂ ʄȸ¼ưВȆϡҷ̫ĚS $ git checkout -b static-pages Rails ȼp5 μʄ̛ʌµƶȸ¼ĩý‚ generateüϬȼpȸ¼ĩ̫ĉŪƊþTѓϡ5ɤ˼ǻUϬµƶ̫ ȸ¼ĩɮŌ̕ҴǙҹҷ̫ѶƊýŮ StaticPages ĎǻUϹ±Ϭ̚ǺŌ̕“ӊҹ”“ƣÍ”ҹҷě“–:”ҹҷ̫Ì kgenerate ĚSþTȷô þѥ̫ìɕȦŲϬ̚Ǻ̫Ìk̓ĴǻUüȼpÌkŠR̀ 3.4 ȁ͈ R̀ 3.4 ̚Ǻ StaticPages ȸ¼ĩ $ rails generate controller StaticPages home help --no-test-framework create app/controllers/static_pages_controller.rb route get "static_pages/help" route get "static_pages/home" invoke erb create app/views/static_pages create app/views/static_pages/home.html.erb create app/views/static_pages/help.html.erb invoke helper create app/helpers/static_pages_helper.rb invoke assets invoke coffee create app/assets/javascripts/static_pages.js.coffee 67 invoke create scss app/assets/stylesheets/static_pages.css.scss ǻUn̛5 --no-test-framework ѥһ͌ʴ̚Ǻ RSpec ˜ЍR̀ĭ$ǻUǯοÌ̚ǺĴ 3.2 ω_Ȃ̵ ƶ˜ЍĈɩǻUіɏDZMĚSϡìɕ ̹ë5 about Ìk͙ĊǻU_̺»Šhѫѐ TDD ˦ÊŮ3.2 ω ˕DZĴR̀ 3.4 `‘ĚS̫ȸ¼ĩĉn̛̫ɮӍƕƻĚĉ˓̚Ǻ̫ȸ¼ĩɘVĉn̛̫ɮϞƱƻĚĉ˓ ĭʶĉ$ StaticPages ̫ȸ¼ĩžư̫ɘVĉ$ static_pages_controller.rbїüɮ ·Ų˜ųĴĚS ϡ n̛ϞƱƻ0þTŠ̫ĚS $ rails generate controller static_pages ... Ĉʠ_̚Ǻ static_pages_controller.rb ȸ¼ĩɘVĭ$ Ruby Ʒòέn̛ӍƕƻĚĉͶĉìϮ 4.4 ωȁTǻħʮ̛ӍƕƻƼ̛ȸ¼ĩǃ˼їɮGħş̫ҕӄĭ$ Ruby ɘV1ǭn̛ϞƱƻĉ͖ȁT Rails ̚Ǻĩ_Л̛ underscore ɟ˓ȏӍƕƻтȮǺϞƱƻ ҼtЗ ŠʔĴ̚ǺR̀ɩ¬̓5ҌЕ̾ѱŠhɅ҉ɈkƊNjɽ̛5ɡ˕ 3.2 KΑ5 AŠhĴ Rails Ʌ҉Ɉk̫ɟ˓ Íå 3.2ÁŦÂ, ånŸƄǏĴƷò Rails ư̛͘Ʈѐ͘ L˼þϊҌƬѓ̫ɮRails ȼp5 AƘ™ιŒƣÍlјϡŎ ê &oʌЗ ƤϮ̫ǧ¥ɮlǯɹɌȸ¼ĩ̫ĉŪїɩlƊϬɅ҉̚Ǻ̫R̀̚Ǻȸ¼ĩɩҦ5ȸ ¼ĩɘVʄс*ŏRails і_̚ǺNj՘P̫ɘVìϮR̀ 3.4Ʌ҉̚Ǻ̫ɘVIIϬ·Ҧ%Ϭ̫ɘ VіϬ·Ҧ AшÍ̫ɘV8ųǻUіϬɅ҉ž routes.rb ɘVο̫̂ AɌÌĴ Rails ǻUþTѫѐ rails destroy ĚSŰǺїAɈk υʌЗҷ̫ĚSɮ̷=Ȗ˟̫ $ rails generate controller FooBars baz quux $ rails destroy controller FooBars baz quux Ĉʠ̫Ĵͩ 6 ͥ _n̛ҷ̫ĚS̚Ǻʬľ $ rails generate model Foo bar:string baz:integer ̚Ǻ̫ʬľþѫѐҷ̫ĚSɅ҉ $ rails destroy model Foo žʬľʌЗǻUþT̹̣ĚSϡ ˜i̫ìɕǃҘЙ»ͩ”ͥɩ̺̺lιčò̓$H(þTї(‚ 68 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ žʬľʌЗˠî»̫û ȎʅɮɅ҉ю͗ͩ 2 ͥƝΒͮϬ̫KΑ5ю͗ͩ 6 ͥƷţ_ɹˤ‘̫KΑю ͗ѫѐҷ̫ĚSɌõɕȰỬ̫Ǚ $ rake db:migrate ǻUþTn̛ҷ̫ĚSɅ҉ ю͗Ɉk $ rake db:rollback ŠʔϬĬ»ɼƷţ̫̉ǙþTn̛ $ rake db:migrate VERSION=0 lþιƝΒ̎»5ƃɕŪ 0 ȮǺ˜P̫ɕŪƊ_Ĭ»̷ư̫̂ʄ̉ǙїÂʄɕŪɮȧ˽ю͗ҼƮȵƮ ̫ ȞɽїAȎʅǻUƊþTnjǏ̫ưžƷòѐ͘ ѯ»̫Ć͑˥4snafu5 ij 3.1 ͈o͘Ʈ̫ config ɘVř 69 R̀ 3.4 ̚Ǻ StaticPages ȸ¼ĩ̫ĚS_οÌɹɞм̜ɘVrouteý‚ config/routes.rbRails _ѫѐ їɘVſȌ URL ěΤҹ*Җ̫žư–΀їɮǻUͩ ʭЂ» config ̴DŽȁTϽǻU̺ В̴DŽ̫Δʐ ĎŠij 3.1config ̴DŽŠ˜ĉŪȁ͈ɮū‡ Rails ư̛͘Ʈ ̫ІΦɘV̫ ĭ$ǻU̚Ǻ5 home ě help Ìkм̜ɘV ƝΒ$ŮU̚Ǻ5ѺΦŠR̀ 3.5 R̀ 3.5 StaticPages ȸ¼ĩ home ě help Ìk̫м̜ѺΦ config/routes.rb SampleApp::Application.routes.draw do get "static_pages/home" get "static_pages/help" . . . end Š̫ϰ³ get "static_pages/home" ij 3.2 ͮҡ̫“ӊҹ”ϱij/static_pages/home 70 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ƃʌο /static_pages/home ̫ИˇɭƂ» StaticPages ȸ¼ĩ̫ home Ìkûŏǃn̛ get ɩ_ƃ˜žư» GET Иˇɟ˓GET ɮ HTTPдɘʄ`ъÝϿHypertext Transfer ProtocolɊȥ̫Ńʄɟ˓* ìϮɡ˕ 3.3ĴǻUїoũ ǃǻUĴ StaticPages ȸ¼ĩ ̚Ǻ home ÌkɩƊοÌ̫Ĵ /static_pages/home ĵĸ ϓnj5 ҹҷЇҕ /static_pages/home þTʙ̺їҹҷŠij 3.2 Íå 3.3GET Ċ дɘʄ`ъÝϿHTTPŲ)5©ŃʄɈkGETPOSTPATCH ě DELETEїīÌЋϥ̓5ŴȀͦ ̞λѫƤ_ѓϡ ˝ϲĩoŠ Firefox Ǽ SafariěɿËĩѫƤ_ѓϡ  Web ɿËĩoŠ Apache Ǽ Nginx*Җ̫Ɉkɽ ˸NjѿϬҲϬl̾ѱǃĴʄĵ̞λƷò Rails ư̛͘ƮɩŴȀͦěɿËĩ ɮĴĈ ̄̕Іō̫cɮ9έɮĈ̫ʫǖô REST ʖʐdžĞ̫ Web ʤʖÓȠ RailsѹNjѿϱ ž HTTP ÌЋ̫ų̓ǻUĴͩ 2 ͥƝΒͮϬKΑ5 RESTMͩ 7 ͥƷţ_‚ɹГΎ̫KΑ GET ɮɼƤ̛̫ HTTP Ɉk̛ʌMΤΗЙóɕȰŮ̫DZǜɮ“Йó Τҹ”ǃlЇҕ google.com Ǽ wikipedia.org ɩl̫˝ϲĩò¬̫Ɗɮ GET ИˇPOST ɮͩ9͑ɼƤ̛̫ɈkǃlȼBϥÞɩ˝ϲĩò ѡ̫Ɗɮ POST ИˇĴ Rails ư̛͘Ʈ POST Иˇ υϧ̛ʌµƶʗϫѐ HTTP 0ŠЄ POST ј ϡɹɞɈkoŠlȼB˕žϥÞɩòѡ̫ POST ИˇƊ_ĴΤͤ µƶ ɞ̛ȀÃ̫ÌЋ PATCH ě DELETE ¯º̛ʌɹɞě҉ʽɿËĩ̫ʗϫїɈkˀ GET ě POST ƅ̛ Aĭ$˝ ϲĩˎɽƶžї͑Иˇ̫ɊȥѐɽA Web ʤʖÓȠ Railsѫѐ Aδɪ̫Ō̕ɟƻ̺гʌƊˆ ɮ˝ϲĩò¬̫ ʠ ҼtЗ Ĵ Rails *À̫̂ʄ ˎɽn̛ PATCH̛̫ɮ PUTRails 4 L˼Ɋȥ PUTc PATCH ιɹ ş̫ϥɪ HTTP Иˇ̫DZijȁTɼşĴɞ̂ n̛ PATCH Ϭǯƺɪ̩їҹҷɮǚ(ʌ̫ϽǻUĴ˝ϲĩ ̺  StaticPages ȸ¼ĩɘVĎlưВ_̺»ͶbR̀ 3.6 ̫ŹlþιƝΒ˕DZ»5ˆͩ 2 ͥ ̫ Users ě Microposts ȸ¼ĩStaticPages ȸ¼ĩˎɽn̛ʜ¦̫ REST ÌkїžҴǙҹҷʌЗɮNjƤϮ̫REST ʖʐƫιϵ¤ȁɽ̫ҕӄ R̀ 3.6 R̀ 3.4 ̚Ǻ̫ StaticPages ȸ¼ĩ app/controllers/static_pages_controller.rb class StaticPagesController < ApplicationController def home end def help end end MҷR̀ ̫ class þT̺» static_pages_controller.rb ɘVŲ)5 Ͷclassý‚ StaticPagesControllerͶɮ ͑΍Ώ®ɕ0ýɟ˓̫ɽɐɟƻoŠ home ě help ÌkƊɮɟ˓n ̛ def –ҎŪŲ)ƇȠĂ < Зɪ StaticPagesController ɮΚȍο Rails ̫ ApplicationController ͶїƊDZĘ̽ǻUŲ)̫ҹҷȞɽ5 Rails ȼp̫œҀÉιǻU_Ĵ 4.4 ω ɹГΎ̫KΑͶěΚȍ 71 Ĵʄo StaticPages ȸ¼ĩ̫ɟ˓әϻѹɮ̫͝ def home end def help end Šʔɮɱѫ̫ Ruby R̀їɟ˓H(0‚5ѐĴ Rails Ɗ ʠ5StaticPagesController ɮ  Ruby Ͷĭ$ŮΚȍο ApplicationControllerŮ̫ɟ˓ž Rails ʌЗƊɽ̆ʻ̫DZ)5 Їҕ /static_pages/home ɩRails Ĵ StaticPages ȸ¼ĩ ſȌ home Ìk˼ĊȆϡВÌkŸ˪ʘ̷ư̫ϱij1.2.6 ω KΑ̫ MVC ̫ VĴʄo home Ìkɮ̫͝ȁTЇҕ /static_pages/home Ċü_˪ʘϱijѶ( ϱijɮH(ʠũǚ(ȃιȌ»ŮĖ ŠʔlŸ̺ R̀ 3.4 ̫ъ¬ǼЄlι̎»Ìkěϱij*Җ̫žư–΀ home Ìkžư̫ϱijý‚ home.html.erb3.3 ωƃĔЊl .erb ɮH(DZǜ̺» .html lǼЄƊ_ŚǞ5ŮŃʄƊɮ HTMLR̀ 3.7 R̀ 3.7 $“ӊҹ”̚Ǻ̫ϱij app/views/static_pages/home.html.erb

StaticPages#home

Find me in app/views/static_pages/home.html.erb

help Ìk̫ϱijR̀ͶbìϮR̀ 3.8 R̀ 3.8 $“ƣÍ”ҹҷ̚Ǻ̫ϱij app/views/static_pages/help.html.erb

StaticPages#help

Find me in app/views/static_pages/help.html.erb

їϱijüɮád̛̫ŮU̫ŹѹÓď5  Έʜӄh1 ʜͭě ɯ͈ϱijɘVŰɗ̷̫žмlj̫ʼ ϕp ʜͭǻU_Ĵ 3.3 ω ˦Ê AͮÞ̫ÌǙŹїAҴǙŹ̫ūĴɮ$5ǁЛ NjѿϬ̫8ǧ Rails ̫ϱijþTüÓďҴǙ̫ HTML ĴʄͥÃ̫Ź ǻU_$“ӊҹ”ě“ƣÍ”ҹҷ˦Ê AŹ˼ĊϤ 3.1 ω ̫“–:”ҹҷ˼Ċ_˦ ÊƅҀ̫ÌǙŹĴʿҹҷɯ͈Ĉ̫ʜӄ ĴΚΛҷ̫Ź*ÀŠʔln̛ Git ̫Џɼşƃ StaticPages ȸ¼ĩ̷–̫ɘVʑNƯ $ git add . $ git commit -m "Add a StaticPages controller" 72 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ 3.2 ĉæŀ ʄ2Ѽ̛5 ̶͑ϯ̫˜Ѝư̛͘Ʈϥ̫̓ɟ˓ή–˕™g̫ų̓ѐ͘їɮ TDD ̫ õ͑ý‚ BDDϡ$ӌÌƷòBehavior-driven DevelopmentǻUn̛̫%ϬƘ™ɮүǺ˜Ѝintegration testěދ˜ Ѝ(unit test)үǺ˜ЍĴ RSpec ý‚ request specيЄǻUʬȝ̛ȀĴ˝ϲĩ ěư̛͘ƮјϡB=̫Ɉk ě Capybara ȼp̫ο˼ДϷú˓natural-language syntax гn̛үǺ˜Ѝȼp5 ͑ǁœ̫ɟ˓ʌ˜Ѝư̛ ͘Ʈ̫Éιή̛Ĵ˝ϲĩ ȂÌʨʙʿҹҷBDD ûŏ ôʮђ̫ѥȟɮ CucumberĴ 8.3 ω _K Α TDD ̫şŌĴ:˜Ѝ^ˀΠ¢ư̛͘Ʈ̫R̀іɨ´ȷ϶̫ЏϬϊ ʼɩҖȃιѢưї͑ɟƻѐşŌNj ɪɯǻU¢ ŗХ˜Ѝfailing test˼ĊΠ¢R̀nї˜ЍѫѐїʠǻUƊ_̷x˜Ѝ̻̫ɮ҂žǻ UІǯ̫Éιї͑“ŗХ-ų̓-ѫѐ”̫ƷòǍ̒Óď5 Ǐ˚þTȼӑΠ̫͘-жƫȼӑɐ̐˜ЍіȊ˲ ̽ư̛͘ƮR̀ŴȀ̫ϴχ_ȼӑфVІϹ̫^Үǝ –: TDD ɽ ˸NjѿϬҲϬl̾ѱŮɮ̛φϑˎǐϬıȆ̫ϻ$ǟɮϬ¢˜Ѝ˜ЍϬĪȠ͘Ʈȁɽ ̫Éιȁɽǧ¥ѹϬ¢˜ЍoŠǃl͆ŲŠhŌ̕ʗAΠ͘ҕӄɩѫƤȹϐlнѐ˜ЍΠ¢R̺̀ ϵ¤ɟ˓ιčϵ¤ҕӄĴʏҤΠ͘ їѐ͘ý‚“ȶ҂ųӎspike” ɦ̺»5ϵ¤ҕӄ̫ɸŽ lƊþTn̛ TDD ų̓ ɹŰΨ̫̂ʄ ʄωǻU_n̛ RSpec ȼp̫ rspec ĚSѓϡ˜Ѝ¶̺гʌїʠ‚ɮ̕ȁǃ˼̫ѐæŰΨŠʔlɮ ӑΈ̛ȀǻƶϿlȧ˽ 3.6 ω̫ŹІΦ l̫΀Ι 3.2.1 æŀŹMŸY Ĵ˜ЍӌÌƷò ǻU¢ _ŗХ̫˜ЍĴNjŐ˜ЍƘ™ _ƃ˜ɯ͈$Άχ˼ĊΠ¢R̀Ͻ˜Ѝѫ ѐɯ͈$ΝχɼĊŠʔҲϬ̫ЏǻUі_ѿʐR̀Ɍõų̫̓ɟƻoŠ˟ҦR̀ѿŎcɌõÉ ιїʠ̫Ʒòѐ͘ý‚“ѯΆõΝѿʐRed, Green, Refactor” ǻUʌn̛ TDD $“ӊҹ”ňÊ AŹ Ź$ Sample App ̫ҺΈʜӄ

ͩ ʷϬ‚̫ɮ$ї AҴǙҹҷ̚ǺүǺ˜Ѝrequest spec $ rails generate integration_test static_pages invoke rspec create spec/requests/static_pages_spec.rb ҷ̫R̀_Ĵ spec/requests ɘVř ̚Ǻ static_pages_spec.rb ɘVοÌ̚Ǻ̫R̀ι˯зǻU ̫Ҳˇ̛ɘʄΠщĩȄƷ static_pages_spec.rbƃ˜ŹɻȮǺR̀ 3.9 ȁ͈̫R̀ R̀ 3.9 ˜Ѝ“ӊҹ”Ź̫R̀ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do describe "Home page" do 73 it "should have the content 'Sample App'" do visit '/static_pages/home' expect(page).to have_content('Sample App') end end end R̀ 3.9 ɮΉͺ̫ RubyѐånlTÀŭ1ѐ Ruby 0̺ŕǷїɮĭ$ RSpec ¹̛5 Ruby ДϷ̫ƵƒǝŲ )5 ŝ“ӁŁƓДϷ”Domain-specific Language, DSL̛ʌ¢˜ЍR̀ѿϬ̫ɮŠʔlǯn̛ RSpec ɮ ŲϬ̾ѱ RSpec ̫ú˓¶̺гʌɮɽA͋ŚRSpec ě Capybara ƊɮїʠІϹ̫ЙгʌNjˆύДŠʔlŐ ̺ʄ2 ̫͈oNjǕlƊ_˾Ό5 R̀ 3.9 Óď5  describe ĻTî˜ ̫ ˜Ѝ̛osampleT it "..." do ƷŘ̫R̀ĻƊɮ  ̛o describe "Home page" do it "should have the content 'Sample App'" do visit '/static_pages/home' expect(page).to have_content('Sample App') end end ͩ ϡR̀ȦɪǻUȻΕ̫ɮ“ӊҹ”ŹƊɮ Ūͨ"ŠʔҲϬlþTn̛Xh̫Ūͨ"RSpec ‚ǁ¼ ϬˇѐlTî˜P̫GͶЙέǼЄ_–Ǐl̛̫Ūͨ"˼Ċ˜ЍЗŠʔlЇҕĵĸ$ /static_pages/ home ̫“ӊҹ”ɩ˜ŹưВÓď“Sample App”їЋěͩ ϡ ʠїðƼĂ ̫Ź RSpec ˎ‚Ϭ ˇüϬι$GͶЙέȼpзŒ̫xǠƊϡ5ҷї ϡ visit '/static_pages/home' n̛5 Capybara ̫ visit ®ɕʌʬȝĴ˝ϲĩ Їҕ /static_pages/home ̫Ɉkҷї ϡ expect(page).to have_content('Sample App') n̛5 page õҀĈʠ̜ Capybara ȼpʌ˜Ѝҹҷ ɮčÓď5ʵ̫͆Ź ϋϬ˜Ѝʵ͆ѓϡǻUϬĴ spec_helper.rb ʑ ϡR̀ŠR̀ 3.10 ȁ͈Ĵʄ2ĊΛ̫Ϗ͛ ǻ Ϲ±Ÿn̛їϡR̀đ̛Éι˜Ѝ ̫ɞȎʅ R̀ 3.10 ȏ Capybara DSL ʑ RSpec ƣÍɘV spec/spec_helper.rb # This file is copied to spec/ when you run 'rails generate rspec:install' . . 74 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ . RSpec.configure do |config| . . . config.include Capybara::DSL end ǻUɽNjŐ͑ɟƻʌѓϡ˜ЍR̀3.6 ω іȼp5 At¹ӑΈ̫ɟ˓̓ĴǻUĴĚSϡ Ȇϡ rspec ĚSÀҷ_Ê bundle exec ʌwЈ RSpec ѓϡĴ Gemfile ȦŲ̫̒Ň  5 $ bundle exec rspec spec/requests/static_pages_spec.rb ѝĚS_ъ¬ ŗХ˜ЍŗХ˜Ѝ̫™gʠũó¤:l̫΀ΙĴǻ̫΀Ι ŮɮΆχ̫Šij 3.36 ij 3.3 ΆχŗХ̫˜Ѝ ϬǯϽ˜ЍѫѐǻUϬ̛R̀ 3.11 ̫ HTML ɻȮȳәϻ̫“ӊҹ”Ź R̀ 3.11 Ͻ“ӊҹ”˜Ѝѫѐ̫R̀ 5. ʿʭѹϬъ‘ bundle exec ɯ˼NjӖ˻ìά 3.6 ω KΑ̫ɟ˓ʌѵъ‘Ů 6. ųҠǻ̫ΐͦěΠщĩηɲѹɮɶχЛ̫ĴǾij n̛Eχɐʔɹş 75 app/views/static_pages/home.html.erb

Sample App

This is the home page for the Ruby on Rails Tutorial sample application.

їʼR̀ Έʜӄ

̫Źɮ Sample App 5_Ͻ˜ЍѫѐǻUіÊ5 ҍЁʜͭ ҈ȷ» ΖŲ̫ĵĸĴҍЁʜͭ ĵĸ̜“href”hypertext referenceȦŲ Ruby on Rails Tutorial ̓ĴŸѓϡ˜Ѝ̺ Δʔ $ bundle exec rspec spec/requests/static_pages_spec.rb Ĵǻ̫΀Ι ѫѐ̫˜Ѝɯ͈Šij 3.4 ȁ͈ ij 3.4 Νχѫѐ̫˜Ѝ 76 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ Ń:ҷ҂ž“ӊҹ”̫oũǼЄlƝΒ̎»5“ƣÍ”ҹҷͶb̫˜Ѝě͘ƮR̀ǻUʌ˜Ѝ ̷ư̫ Ź̓ĴŪͨ"õǺ“Help”5ìϮR̀ 3.12 R̀ 3.12 ˦ʘЍ“ƣÍ”ҹҷŹ̫R̀ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do describe "Home page" do it "should have the content 'Sample App'" do visit '/static_pages/home' expect(page).to have_content('Sample App') end end describe "Help page" do it "should have the content 'Help'" do visit '/static_pages/help' expect(page).to have_content('Help') end end end ˼Ċѓϡ˜Ѝ $ bundle exec rspec spec/requests/static_pages_spec.rb ɽ ˜Ѝ_ŗХĭ$΀Ι̫ĈήΙϹʿҜʼ̫˜ЍɕҀNjҭM̓ĴƷţǻƊ_ŸǾij RSpec ̫ ъ¬Δʔ5 ͘ƮȁҲ̫R̀ěR̀ 3.11 ͶbŠR̀ 3.13 ȁ͈ R̀ 3.13 Ͻ“ƣÍ”ҹҷ̫˜Ѝѫѐ̫R̀ app/views/static_pages/help.html.erb

Help

Get help on the Ruby on Rails Tutorial at the Rails Tutorial help page. To get help on this sample app, see the Rails Tutorial book.

̓Ĵ˜ЍưВþTѫѐ5 77 $ bundle exec rspec spec/requests/static_pages_spec.rb 3.2.2 éLŲű ̺ѐ5ҷͮÞ̫ TDD Ʒòѐ͘ҷǻUϬ̛їȎʅŰǺ ͙ǎŎʇ A̫XË˦Ê ɞҹҷƊɮ 3.1 ω ˎɽ̚Ǻ̫“–:”ҹҷѫѐʿ ʷ Π¢˜Ѝěѓϡ RSpec ̫ѐ͘ǻU_̺» TDD ɮŠhƼƀǻUј ϡư̛͘ƮƷò̫ ŝē ʌ»“ѯΆ-õΝ”ѐ͘ ̫“ѯΆ”Ѹ¯$“–:”ҹҷ¢ ŗХ˜Ѝì˽R̀ 3.12 ̫R̀ǼЄlƝΒ̾ѱŠ h¢ї˜Ѝ5ìϮR̀ 3.14 R̀ 3.14 ˦ʘЍ“–:”ҹҷŹ̫R̀ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do describe "Home page" do it "should have the content 'Sample App'" do visit '/static_pages/home' expect(page).to have_content('Sample App') end end describe "Help page" do it "should have the content 'Help'" do visit '/static_pages/help' expect(page).to have_content('Help') end end describe "About page" do it "should have the content 'About Us'" do visit '/static_pages/about' expect(page).to have_content('About Us') end end end 78 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ [ĝ ĬҾ  3.1 ω̫ŹĴ Rails ǻUþTѫѐµƶ Ìkƫ˦Ê̷ư̫ϱijɘVʌ̚ǺҴǙҹҷȁTӊǻ UϬĴ StaticPages ȸ¼ĩ ˦Ê  about ÌkǻUƝΒ¢ѐŗХ˜Ѝ5̓ĴƝΒ͆xŠʔιѫѐƊµ ƶ5 þTѓϡ̫“–:”ҹҷ Šʔlѓϡ RSpec ˜Ѝ $ bundle exec rspec spec/requests/static_pages_spec.rb ъ¬̫Δʔ_ȼ͈ҷ̫ҌЕ No route matches [GET] "/static_pages/about" їȼѻǻUϬĴм̜ɘV ˦Ê static_pages/aboutǻUþTȧ˽R̀ 3.5 ȁ͈̫ʣƻ˦ÊΔʔŠR̀ 3.15 ȁ͈ R̀ 3.15 ˦Ê“–:”ҹҷ̫м̜ config/routes.rb SampleApp::Application.routes.draw do get "static_pages/home" get "static_pages/help" get "static_pages/about" . . . end ̓Ĵѓϡ˜Ѝ $ bundle exec rspec spec/requests/static_pages_spec.rb ƃȼ͈ŠҌЕ The action 'about' could not be found for StaticPagesController $5ϵ¤їҕӄǻUȧ˽R̀ 3.6 home ě help ̫ʣƻĴ StaticPages ȸ¼ĩ ˦Ê about Ìk̫R̀Š R̀ 3.16 ȁ͈ R̀ 3.16 ˦Ê5 about Ìk̫ StaticPages ȸ¼ĩ app/controllers/static_pages_controller.rb class StaticPagesController < ApplicationController def home end 79 def help end def about end end Ÿѓϡ˜Ѝ $ bundle exec rspec spec/requests/static_pages_spec.rb _ȼ͈ΣƅʬʎtemplateoŠ ϱij Missing template static_pages/about Ϭϵ¤їҕӄǻUϬ˦Ê about Ìkžư̫ϱijǻUҲϬĴ app/views/static_pages ̴DŽµƶ  ĉ$ about.html.erb ̫ɞɘV¢‘R̀ 3.17 ȁ͈̫Ź R̀ 3.17 “–:”ҹҷϱijR̀ app/views/static_pages/about.html.erb

About Us

The Ruby on Rails Tutorial is a project to make a book and screencasts to teach web development with Ruby on Rails. This is the sample application for the tutorial.

Ÿѓϡ RSpec ƊưВ“õΝ”5 $ bundle exec rspec spec/requests/static_pages_spec.rb ǃ˼Ĵ˝ϲĩ ʙ̺ їҹҷʌ͆w˜Ѝˎɽŗɐ0ɮҌ̫%DZŠij 3.5 Ţ× ̓Ĵ˜ЍƝΒõΝ5ǻUþTNjοx̫ƌǧѿʐ5ǻU̫R̀ΒƤ_“õĘ”DZǜɮR̀_õnjҡĥĨ œҀ̫ѿŎ̞λ_ĴDZcɮGͶ_ȁTΒƤѿʐϽR̀õnjͮ˖ɮNjѿϬ̫їɩ| ş̫˜ЍƊɯ ¬˜W~5ĭ$ŮþTңeѿʐѐ͘ Ƽ‘ bug ̫ӈҧ ǻU̫͈o͘Ʈ̓ĴіNjƄˎH(þѿʐ̫ѐR̀ɣɩɣ¾ĴõĘȁTǻU̫ѿʐ0_ͪNj' Ĵ 3.3.4 ω ƊϬǔ:ѿʐ5 80 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ 3.3 ÒîM©=ˆûŲű »̴À$ʴǻUƝΒ$ AҴǙҹҷµƶ5ÌkěϱijǻUіɌõ5ʿ ҹҷɯ͈̫ŹʜӄϽŮ̺г ʌɮÌǙ̫Ɍõʜӄ»Ʊ̻ͯͯʵÌǙіɽ7ϿѐÀҷ̫ŹæþT$ͩ 7 ͥKΑ̫̻ʵÌǙȄŃ̈́ Šʔlнѐ5 3.2 ω ̫ TDD Ѹ¯ĴΚΛҘЙ*ÀИȧ˽R̀ 3.15R̀ 3.16 ěR̀ 3.17 µƶ“–:”ҹҷ ij 3.5 ɞ˦Ê̫“–:”ҹҷ/static_pages/about 3.3.1 æŀÛŷû[O ǻUϹ±yɌ“ӊҹ”“ƣÍ”ҹҷě“–:”ҹҷ̫ʜӄĴʿ ҹѹɽȁõÔїѐ͘ƃn̛ϱij ̫ ʜͭœŐɕ˝ϲĩ_Ĵ˝ϲĩ͠ø̫ҺѸɯ͈ʜӄ̫ŹGoogle Chrome ɮ̆oʜӄžȿ΂Ƽɉ^Ô0 ɮNjѿϬ̫ǻU_¢˜Ѝʜӄ̫R̀˼Ċ˦ÊʜӄɼĊn̛ƞƎlayoutɘVјϡѿʐ¿ҦѿŎ lþιƝΒ˕DZ»5rails new ĚSƝΒµƶ5ƞƎɘV͙ĊǻU_KΑїɘV̫k̛̓ĴĴΚΛ*À ƃ˜ѿĚĉ $ mv app/views/layouts/application.html.erb foobar # #ɩyɌ mv ɮ Unix ĚSĴ Windows lþTĴɘV˝ϲĩ ѿĚĉǼέn̛ rename ĚSĴ̻ʵ̫ư̛͘Ʈ l ҲϬї(‚ѐˎɽ5їɘV*ĊlƊιɹŹɫ̕ϵŮ̫k̛ 81 ʄωΔʉĊҴǙҹҷ̫ʜӄѹ_ɮ“Ruby on Rails Tutorial Sample App | Home”ї͑Džƻʜӄ̫Ċҷ Ѹ¯_ ʢȰȁĴ̫ҹҷήɽȁĈìϮϥʣ 3.1ǻUȷ̽R̀ 3.14 ̫˜Ѝ˦ÊR̀ 3.18 ȁ͈˜Ѝʜӄ̫R̀ R̀ 3.18 ʜӄ˜Ѝ it "should have the right title" do visit '/static_pages/home' expect(page).to have_title("Ruby on Rails Tutorial Sample App | Home") end have_title ɟ˓_˜Ѝ  HTML ҹҷʜӄ ɮčďɽȦŲ̫ŹȮúЏЗҷ̫R̀ expect(page).to have_title("Ruby on Rails Tutorial Sample App | Home") _ʨʙ title ʜ̫ͭŹɮč$ "Ruby on Rails Tutorial Sample App | Home" Ϭ˕DZ ʨʙ̫Ź ŲϬےÖѺXh̫ũŪͨ"ѹþTȁT expect(page).to have_title("Home") 0_ÖѺŰɗDžƻ̫ʜӄ ҹҷ ϥʣ 3.1 ͈o͘Ʈ ŃʄɮҴǙŹ̫ҹҷ URL Ńʄʜӄ õÌѸ¯ ӊҹ /static_pages/home "Ruby on Rails Tutorial Sample App" "Home" ƣÍ /static_pages/help "Ruby on Rails Tutorial Sample App" "Help" –: /static_pages/about "Ruby on Rails Tutorial Sample App" "About" ǻUȧ˽R̀ 3.18 ̫ʣƻ$ҴǙҹҷѹʘЍR̀Δʔì˽R̀ 3.19˕DZ˜Ѝ ɽNjŐѿŎǻU_ Ĵ 5.3.4 ωѿʐ R̀ 3.19 StaticPages ȸ¼ĩ̫˜ЍɘVÓďʜӄ˜Ѝ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do describe "Home page" do it "should have the content 'Sample App'" do visit '/static_pages/home' 82 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ expect(page).to have_content('Sample App') end it "should have the title 'Home'" do visit '/static_pages/home' expect(page).to have_title("Ruby on Rails Tutorial Sample App | Home") end end describe "Help page" do it "should have the content 'Help'" do visit '/static_pages/help' expect(page).to have_content('Help') end it "should have the title 'Help'" do visit '/static_pages/help' expect(page).to have_title("Ruby on Rails Tutorial Sample App | Help") end end describe "About page" do it "should have the content 'About Us'" do visit '/static_pages/about' expect(page).to have_content('About Us') end it "should have the title 'About Us'" do visit '/static_pages/about' expect(page).to have_title("Ruby on Rails Tutorial Sample App | About Us") end end end ̓ĴƝΒɽ5ŠR̀ 3.19 ȁ͈̫˜ЍlưВѓϡ $ bundle exec rspec spec/requests/static_pages_spec.rb ͆wnj»̫ΔʔɮΆχ̫ŗХ̫˜Ѝ 83 3.3.2 ĹÛŷæŀŚŒ ̓ĴǻUϬϽʜӄ˜ЍѫѐĈɩǻUіϬŰĦ HTMLϽŮѫѐӎЈͨćɼɞʜ¦̫ҹҷΔʐɮҷї͑Džƻ ̫ <!DOCTYPE html> <html> <head> <title>Greeting

Hello, world!

ї͑Δʐ̫ɼҺѸÓď ɘʦͶľŋɪdocument type declaration͖ͮ doctypeĔ̾˝ϲĩȁ̛̫ HTML ̂ ʄʄon̛ HTML57ҩĊɮ head Ѹ¯Óď  title ʜͭ˜Ź$“Greeting”˼Ċɮ body Ѹ¯ Óď  p ʜͭϥ͈ʼϕ˜Ź$“Hello, world!”ɘVŹ̫΢јɮþѥ̫HTML _̆ºžNJ͝ ̩Tab ě͝ʣѹ_ϧỤ̈́c΢јþTϽɘʦɹɫҘЙ Ĵ“ӊҹ” n̛ї͑ŃʄΔʐĊnj»̫ɘʦŠR̀ 3.20 ȁ͈ R̀ 3.20 “ӊҹ”̫Űɗ HTML app/views/static_pages/home.html.erb Ruby on Rails Tutorial Sample App | Home

Sample App

This is the home page for the Ruby on Rails Tutorial sample application.

R̀ 3.20 n̛5R̀ 3.19 ˜Ѝ̛»̫ʜӄ Ruby on Rails Tutorial Sample App | Home 7. HTML ̶ĴõÔɯƻŋɪ  doctype þT͆w˝ϲĩĴʂʌіþTʵ̫͆ϵʑҹҷ ї͑ʏ$ͮÞ ̫ʣƻɮɼɞ̫ HTML ʜ¦ HTML5 ̫ ̆χ 84 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ȁT“ӊҹ”̫˜Ѝ̓ĴưВþTѫѐ5lі_̺»Άχ̫ҌЕȼ͈ɮĭ$“ƣÍ”ҹҷě“–:”ҹҷ̫˜Ѝіɮ ŗХ̫ǻUn̛R̀ 3.21 ěR̀ 3.22 ̫R̀ϽŮU0ѫѐ˜Ѝ R̀ 3.21 “ƣÍ”ҹҷ̫Űɗ HTML app/views/static_pages/help.html.erb Ruby on Rails Tutorial Sample App | Help

Help

Get help on the Ruby on Rails Tutorial at the Rails Tutorial help page. To get help on this sample app, see the Rails Tutorial book.

R̀ 3.22 “–:”ҹҷ̫Űɗ HTML app/views/static_pages/about.html.erb Ruby on Rails Tutorial Sample App | About Us

About Us

The Ruby on Rails Tutorial is a project to make a book and screencasts to teach web development with Ruby on Rails. This is the sample application for the tutorial.

3.3.3 ‘8¡ Ruby ʄω»̴À$ʴƝΒ‚5NjŐ8ǧǻUѫѐ Rails ȸ¼ĩěÌk̚Ǻ5þTѫѐú˓ӎЈ̫ҹҷѐїA ҹҷѹɮΉҴǙ̫ HTMLˎɽg̓¬ Rails ̫ǁœȁĴήŮU̫R̀Œɛ̽ѿŎ • ҹҷ̫ʜͭ©+cےɮ ʬ ʠ̫ 85 • ʿʜӄ ѹɽ“Ruby on Rails Tutorial Sample App” • HTML ΔʐĴʿҹҷѹѿŎ̫¬̓5 R̀ѿŎ̫ҕӄњñ5NjѿϬ̫“ϬοǻѿŎ”Don’t Repeat Yourself, DRYê³ʄƄωě Ƅωƃȧ˽ DRY ê³ëȳѿŎ̫R̀ ѐǻUëҦѿŎ̫ͩ ʷæɮϬňÊ AR̀Ͻҹҷ̫ʜӄ̺гʌɮ ʠ̫їʠǻUƊþTɹŹɫ̫ëȳѿŎ ̫R̀5 їѐ͘_Ĵϱij n̛Ɩ‘ƻ RubyEmbedded Rubyɤ˼“ӊҹ”“ƣÍ”ҹҷě“–:”ҹҷ̫ʜӄɽ õ Ì̫Ѹ¯ѶǻUƊ¹̛  Rails ̆º̫®ɕ provide ĴʿҹҷІŲĈ̫ʜӄѫѐƃϱij home.html.erb ʜӄ ̫“Home”ȮǺŠR̀ 3.23 ȁ͈̫R̀ǻUþT̺ ų̫̓ѐ͘ R̀ 3.23 ʜӄ n̛5Ɩ‘ƻ Ruby R̫̀“ӊҹ”ϱij app/views/static_pages/home.html.erb <% provide(:title, 'Home') %> Ruby on Rails Tutorial Sample App | <%= yield(:title) %>

Sample App

This is the home page for the Ruby on Rails Tutorial sample application.

R̀ 3.23 ǻUͩ ʭn̛5Ɩ‘ƻ Ruby͖ͮ ERb̓ĴlưВ̾ѱ$H( HTML ϱijɘV̫ȇƒĉɮ .html.erb 5ERb ɮ$Τҹ˦ÊÌǙŹn̛̫%Ϭʬʎ΀Ι8ҷ̫R̀ <% provide(:title, 'Home') %> ѫѐ <% ... %> Л̛ Rails ̫ provide ®ɕ˼ĊƃŪͨ" 'Home' ЭΖ :title9˼ĊĴʜӄ ǻU n̛Ͷb̫ͨĂ <%= ... %> ѫѐ Ruby ̫ yield ®ɕƃʜӄȽ‘ʬʎ 10 Ruby on Rails Tutorial Sample App | <%= yield(:title) %> 8. ˜ųіɽûŏ ôʮђ̫ʬʎ΀Ιý HamlǻGNjħʮ̛ѐĴїʠ̫¶Έɓ͘ n̛ŕćѢ 9. Βӎ!Ż̫ Rails ƷòέþιϳnjїѾưВn̛ content_forþɮŮĴ asset pipeline ιNjş̫Ƙkprovide ®ɕɮ ɻRɟ˓ 10. Šʔlŭ1ѐ Rubyþι_̎˜ Rails ɮƃŹȣ‘×Ļ ̫їʠǯ0ɮž̫ѐn̛ Rails Ʒòư̛͘Ʈǐ̾ѱї ˸ 86 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ї͑Ɩ‘ Ruby R̫̀ɟƻ׺Ĵ:<% ... %> Ȇϡ˜ ̫R̀<%= ... %> 0_Ȇϡ˜ ̫R̀ή _ȏȆϡ̫ΔʔȽ‘ʬʎ ɼΐnj»̫ΔʔěTÀɮ ʠ̫üѐʜӄ õÌ̫Ѹ¯̓Ĵɮѫѐ ERb ÌǙ ̚Ǻ̫ ǻUþTѓϡ 3.3.1 ω ̫˜ЍʌЈų ˜Ѝіɮ_ѫѐ $ bundle exec rspec spec/requests/static_pages_spec.rb ˼ĊǻUϬž“ƣÍ”ҹҷě“–:”ҹҷ‚̷ư̫yɌ5ìϮR̀ 3.24 ěR̀ 3.25 R̀ 3.24 ʜӄ n̛5Ɩ‘ƻ Ruby R̫̀“ƣÍ”ҹҷϱij app/views/static_pages/help.html.erb <% provide(:title, 'Help') %> Ruby on Rails Tutorial Sample App | <%= yield(:title) %>

Help

Get help on the Ruby on Rails Tutorial at the Rails Tutorial help page. To get help on this sample app, see the Rails Tutorial book.

R̀ 3.25 ʜӄ n̛5Ɩ‘ƻ Ruby R̫̀“–:”ҹҷϱij app/views/static_pages/about.html.erb <% provide(:title, 'About Us') %> Ruby on Rails Tutorial Sample App | <%= yield(:title) %>

About Us

The Ruby on Rails Tutorial is a project to make a book and screencasts to teach web development with Ruby on Rails. This is the sample application for the tutorial.

87 3.3.4 -ö–É(ÖèŬŢy ǻUƝΒn̛ ERb ƃҹҷʜӄ õÌ̫Ѹ¯ɻȮȳ5ʿ ҹҷ̫R̀NjͶb <% provide(:title, 'Foo') %> Ruby on Rails Tutorial Sample App | <%= yield(:title) %> ȮúЏЗȁɽ̫ҹҷΔʐѹɮ ρ̫ÓȠ title ʜͭ ̫Źüɽ body ʜͭ ̫ŹɽΎǎ̫ƛº $5ȼó¬̷Ĉ̫ΔʐRails ȼp5 ̆º̫ƞƎɘVý‚ application.html.erbǻUĴ 3.3.1 ω ƃ ŮѿĚĉ5̓ĴǻUŸɌĬʌ $ mv foobar app/views/layouts/application.html.erb $5ϽƞƎʵƤ̫ѓϡǻUϬȏәϻ̫ʜӄɌ$À©oR̀ n̛̫Ɩ‘ƻ Ruby R̀ Ruby on Rails Tutorial Sample App | <%= yield(:title) %> ɼΐ̫ƞƎɘVŠR̀ 3.26 ȁ͈ R̀ 3.26 ͈o͘Ʈ̫ΤͤƞƎ app/views/layouts/application.html.erb Ruby on Rails Tutorial Sample App | <%= yield(:title) %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> 88 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ <%= yield %> ˕DZ ˀч̆ʻ̫ ϡ <%= yield %> їϡR̀ɮ̛ʌƃʿ ҹ̫ŹȽ‘ƞƎ ̫ˎǐϬ5ϵŮ̫™gų̓ѐ͘ǻUüҲϬ̾ѱĴƞƎ n̛ ĊǃЇҕ /static_pages/home ɩ_ƃ home.html.erb ̫ŹтȮǺ HTML ˼ĊȽ‘ <%= yield %> ȁĴ̫ dΦ іϬ˕DZ әϻ̫ Rails ƞƎɘVÓď©ϡ̆ʻ̫R̀ <%= stylesheet_link_tag ... %> <%= javascript_include_tag "application", ... %> <%= csrf_meta_tags %> їAR̀_Ƽ‘ư̛͘Ʈ̫ʠƻϥě JavaScript ɘVasset pipeline ̫ Ѹ¯ Rails ̫ csrf_meta_tags ɟ ˓ɮ̛ʌѵ“лͤИˇaѭ”cross-site request forgeryCSRF ͑ΤΗɍ­̫ ̓ĴR̀ 3.23R̀ 3.24 ěR̀ 3.25 ̫ŹіɮěƞƎɘV Ͷb̫ HTMLȁTǻUϬƃŹ·Ҧüw̢Ҳ Ϭ̫Ѹ¯˧̕Ċ̫ϱijŠR̀ 3.27R̀ 3.28 ěR̀ 3.29 ȁ͈ R̀ 3.27 ëҦŰɗ̫ HTML ΔʐĊ̫“ӊҹ” app/views/static_pages/home.html.erb <% provide(:title, 'Home') %>

Sample App

This is the home page for the Ruby on Rails Tutorial sample application.

R̀ 3.28 ëҦŰɗ̫ HTML ΔʐĊ̫“ƣÍ”ҹҷ app/views/static_pages/help.html.erb <% provide(:title, 'Help') %>

Help

Get help on the Ruby on Rails Tutorial at the Rails Tutorial help page. To get help on this sample app, see the Rails Tutorial book.

89 R̀ 3.29 ëҦŰɗ̫ HTML ΔʐĊ̫“–:”ҹҷ app/views/static_pages/about.html.erb <% provide(:title, 'About Us') %>

About Us

The Ruby on Rails Tutorial is a project to make a book and screencasts to teach web development with Ruby on Rails. This is the sample application for the tutorial.

yɌї©ϱijĊ“ӊҹ”“ƣÍ”ҹҷě“–:”ҹҷɯ͈̫Źіě*À ʠcɮæˎɽѿŎ̫Ź5ѓϡ ˜Ѝ̺ɮčі_ѫѐѫѐ5ȃιЈųѿʐɮǺÉ̫ $ bundle exec rspec spec/requests/static_pages_spec.rb 3.4 ŒĘ ǟ̫ʌЗʄͥ©+ˎɽ‚H( ǻUMҴǙҹҷƷţɼĊŰǺ̫©+іɮҴǙ̫ҹҷѐMϥҷʌ̺ǻUn ̛5 Rails ̫ȸ¼ĩÌkěϱijјϡƷòƘk̓ĴǻUƝΒþTċǻU̫Τͤ ˦ÊXDZ̫ÌǙŹ5ʄ ɓ̫͘Ċ˝Ź_ĔЊlǚ(˦Ê ĴΚΛ*ÀϽǻUϊ ˸ɩҖȼBʄ̫ͥɌÌ˼Ċƃ˜ćƫ»%¯Ɋ Ĵ 3.1 ω ǻU$ҴǙҹҷ̫ƷòƘ kµƶ5  Git ɞ¯ɊĴƷò̫ѐ͘ Šʔlіˎɽ‚ȼBѶ(ʌ‚ ʭȼBĎĭ$ǻUƝΒŰǺ5 AƘk $ git add . $ git commit -m "Finish static pages" ˼Ċ¹̛ 1.3.5 ω KΑ̫ȎʅƃõÌćƫ»%¯Ɋ $ git checkout master $ git merge static-pages ʿʭŰǺ AƘkĊɼşƃR̀ȹѡ»љ̫ͦNƯŠʔlȧ˽ 1.3.4 ω ̫ʷӏ‚5љͦNƯƊĴ GitHub  $ git push ŠʔlǴDZ̓ĴlіþTƃɌş̫ư̛͘ƮѸΧ» Heroku  $ git push heroku 90 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ 3.5 Ė 1. $͈o͘Ʈ¼k “γ΀”ҹҷlþTì˽R̀ 3.19Π¢ ˜Ѝ̛oʨ˜ҹҷ̫ʜӄɮč$ “Ruby on Rails Tutorial Sample App | Contact”͆Ų /static_pages/contact žư̫ҹҷɮčūĴƃR̀ 3.30 ̫Ź ¢‘“Ό1”ҹҷϽ˜ЍþTѫѐїΌ1_Ĵ 5.3 ω ϵ¤ 2. lþιƝΒò̓ StaticPages ˜ЍɘVR̀ 3.19 ɽѿŎ̫ĵɟ“Ruby on Rails Tutorial Sample App”Ĵ ʿʜӄ˜Ѝ ѹ¬̓5n̛ RSpec ̫ let ®ɕƃ~ЭΖõҀ͆wR̀ 3.31 ̫˜ЍL˼ɮѫѐ ̫R̀ 3.31 n̛5Ūͨ"Ƚ~interpolation_Ĵ 4.2.2 ω KΑ 3. ҟÊӄHeroku Τͤ ͳKΑŠhĴƷò̒Ň n̛ sqlite3 ̫ɘͥȼ»ɼşĴƷò̒Ň˜Ѝ̒Ň ě̚C̒Ň n̷̛ĈͶľ̫ɕȰƯȧ˽ Heroku ΤͤKΑŠhĴʄĵ̒Ň ůϪ PostgreSQL ̫ɘͥ ŹĴl̫̞λůϪ PostgreSQL ɕȰƯyɌ Gemfile·ȳ sqlite3Ȯ pgŠR̀ 3.32 ȁ ͈lіϬ̾ѱŠhyɌ config/database.yml ɘVTîŠhĴʄĵѓϡ PostgreSQL ɕȰƯї Ό1̴̫ʜɮn̛ PostgreSQL ɕȰƯµƶƫІΦƷò̒Ňě˜Ѝ̒Ň ̛»̫ɕȰƯǻ̆ºȹϐn̛ Induction ћȷƫʙ̺ʄĵ PostgreSQL ɕȰƯ˕DZ l_ò̓ʄӄіɮɽ˸ҭƴ̫ǻüȹϐӑΈ̛Ȁ ‚ї ӄŠʔlĴʗĵɟâf5ϬļȥɎÀҷǻƝΒЗѐ5ʄɓ͘Ʒò̫͈o͘Ʈے› Ź SQLite ě PostgreSQL R̀ 3.30 “Ό1”ҹҷ̫Ź app/views/static_pages/contact.html.erb <% provide(:title, 'Contact') %>

Contact

Contact Ruby on Rails Tutorial about the sample app at the contact page.

R̀ 3.31 n̛5 ѫ̛ʜӄ̫ StaticPages ˜ЍɘV spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do let(:base_title) { "Ruby on Rails Tutorial Sample App" } describe "Home page" do it "should have the content 'Sample App'" do visit '/static_pages/home' expect(page).to have_content('Sample App') end it "should have the title 'Home'" do visit '/static_pages/home' 91 expect(page).to have_title("#{base_title} | Home") end end describe "Help page" do it "should have the content 'Help'" do visit '/static_pages/help' expect(page).to have_content('Help') end it "should have the title 'Help'" do visit '/static_pages/help' expect(page).to have_title("#{base_title} | Help") end end describe "About page" do it "should have the content 'About Us'" do visit '/static_pages/about' expect(page).to have_content('About Us') end it "should have the title 'About Us'" do visit '/static_pages/about' expect(page).to have_title("#{base_title} | About Us") end end describe "Contact page" do it "should have the content 'Contact'" do visit '/static_pages/contact' expect(page).to have_content('Contact') end it "should have the title 'Contact'" do visit '/static_pages/contact' expect(page).to have_title("#{base_title} | Contact") end end end R̀ 3.32 ·Ҧ SQLite n̛ PostgreSQL ɕȰƯȁҲ̫ Gemfile ɘV 92 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' gem 'pg', '0.15.1' group :development, :test do gem 'rspec-rails', '2.13.1' end group :test do gem 'selenium-webdriver', '2.0.0' gem 'capybara', '2.1.0' end gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' gem 'jquery-rails', '2.2.1' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' group :doc do gem 'sdoc', '0.3.20', require: false end 3.6 żĕµÔ 3.2 ω ɺΒȼ»ѐ̶ȷn̛ rspec ĚSɮ̕ǯ̫ѥȟĴʄωǻU_KΑ ɟ˓ѵъ‘ bundle exec˼Ċ_KΑŠhn̛ Guard3.6.2 ωTîþѥ̫ Spork3.6.3 ωų̓οÌѓϡ˜Ѝ̫ÉιɼĊǻU_ KΑ ͑Šh̶ȷĴ Sublime Text ѓϡ˜Ѝ̫ɟ˓ї͑Ȏʅě Spork гn̛ɩ̆ºɟt ʄω̫Źü҂žӑΈ̛Ȁнѐї ω_džĞĊҷ̫Ź̷ˀʄ2˜P̫Ѹ¯ї ω̫ŹþιNjǕƊѐ ɩ5ȁTlϬʁ̸Ĵl̫΀Ι n̛ɩnj»̫ΔʔěїѾ̫ ʠlþT¹̛ Google ͆w °ѹιʵƤѓϡ 3.6.1 U¸ bundle exec 3.2.1 ω ȼ»ѐ υǻUϬĴ rake Ǽ rspec ĚSÀÊ bundle execїʠȃιwЈǻUѓϡ̫͘ƮƊɮ Gemfile ȦŲ̫̂ʄŃ:Ȏʅ̫êĭrails ĚSɮoŏї͑‚˓NjĥĨʄω_KΑ͑ɟ˓ ѵї(‚ 93 ٬ Bundler û RVM ͩ 0ɮȹϐ̫ɟ˓ɮn̛ RVMM V1.11 ƷţŮƊүǺ5 BundlerlþTѓϡҷ̫ĚS͆wοƜn̛̫ ɮ RVM ɼɞ̂ $ rvm get stable $ rvm -v rvm 1.19.5 (stable) üϬ̂ʄɮ 1.11.x ǼTůϪ̫ gem Ɗ_Ĵ̆Ų̫ Bundler ̒Ň ȆϡȁTlƊþT̶ȷѓϡ $ rspec spec/ ή̛ÊÀҷ̫ bundle execŠʔlǺÉ5Ѷ(ƊþTнѐʄƄωÃ̫Ź5 Šʔ̜:ʗ͑êĭɣ˓n̛чɞ̫̂ RVMlіþTѫѐn̛үǺ Bundler ȁҲ̫ gemѺΦ RVM ϽŮĴʄĵ̒Ň οÌÓď̷ư̫þȆϡɘVїʠ0ιëȳ bundle execŠʔlşŚ̫Џ˜ųʷӏNjͮÞӊȆϡ ҷ̫ĚS $ rvm get head && rvm reload $ chmod +x $rvm_path/hooks/after_cd_bundler ˼ĊȆϡ $ cd ~/rails_projects/sample_app $ bundle install --without production --binstubs=./bundler_stubs їAĚS_ѫѐʗ͔̫͑͋ÇҀƃ RVM ě Bundler ΍ćĴ г͆wŠ rake ě rspec ͪĚSþTοÌ̫Ĵʵ͆ ̫̒Ň Ȇϡĭ$їAɘVɮ҂žlʄĵ̒Ň̫lưВƃ bundler_stubs ɘVřʑ .gitignore ɘV ìϮR̀ 3.33 R̀ 3.33 ȏ bundler_stubs ʑ .gitignore ɘV # Ignore bundler config. /.bundle # Ignore the default SQLite database. /db/*.sqlite3 /db/*.sqlite3-journal # Ignore all logfiles and tempfiles. /log/*.log /tmp # Ignore other unneeded files. 94 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ doc/ *.swp *~ .project .DS_Store .idea bundler_stubs/ Šʔl˦Ê5˜P̫þȆϡɘVoŠĴ 3.6.2 ω ʑ5 guardlϬѿɞѓϡ bundle install ĚS $ bundle install --binstubs=./bundler_stubs binstubs Šʔlˎn̛ RVM 0þTѵъ‘ bundle execBunlder ŠЄlѫѐҷ̫ĚS̚Ǻ̷–̫þȆϡ͘Ʈ $ bundle --binstubs $ bundle config --delete bin && rm -rf bin $ rake rails:update:bin 8ųϝ˼їѾ̛̫ɮĈ̴̫ʜ̴DŽѐ RVM 0þTn̛ŮїĚS_Ĵư̛͘Ʈ ̫ bin/ ɘV ř ̚Ǻȁɽǐҽ̫þȆϡɘVȁTǻUƊþTѫѐҷ̫ɟƻѓϡ˜Ѝ5 $ bin/rspec spec/ ž rake ͪʌЗɮ ʠ̫ $ bin/rake db:migrate Šʔl˦Ê5˜P̫þȆϡɘVoŠ 3.6.2 ω ̫ guardҲϬѿɞȆϡ bundle --binstubs ĚS ҁ:ʗAЙέ_нѐї ωʄɓ̫͘Ċ˝Źіɮ_n̛ bundle execѵ¬̓ҌЕѐŠʔl̫΀Ι ƝΒ‚5ʵ̫͆ІΦlưВn̛ɹͮ˖̫Džƻ 3.6.2 -ö Guard ĩMæŀ n̛ rspec ĚSɽ ˸Nj˻GlǟɮϬ°Ȯ»ĚSϡ˼ĊȂÌъ‘ĚSȆϡ˜Ѝû Nj˻G̫8ǧɮ ˜Ѝ̫đÌɩҖNjǶ3.6.3 ω_ЗɪʄωǻU_KΑŠhn̛ Guard οÌѓϡ˜ЍGuard _̯ϱɘV΀Ι̫õ Ì€ŠlyɌ5 static_pages_spec.rbѶ(üɽїɘV ̫˜Ѝ_ϧѓϡήǻUþTѢǃ̫ІΦ Guardǃ home.html.erb ϧyɌĊ0_οÌѓϡ static_pages_spec.rb ӊǻUϬȏ guard-rspec ʑ GemfileìϮR̀ 3.34 R̀ 3.34 ͈o͘Ʈ̫ GemfileÓď Guard 95 source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' group :development, :test do gem 'sqlite3', '1.3.7' gem 'rspec-rails', '2.13.1' gem 'guard-rspec', '2.5.0' end group :test do gem 'selenium-webdriver', '2.0.0' gem 'capybara', '2.1.0' # Uncomment this line on OS X. # gem 'growl', '1.0.3' # Uncomment these lines on Linux. # gem 'libnotify', '0.8.0' # Uncomment these lines on Windows. # gem 'rb-notifu', '0.0.4' # gem 'win32console', '1.3.2' end gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' gem 'jquery-rails', '2.2.1' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' group :doc do gem 'sdoc', '0.3.20', require: false end group :production do gem 'pg', '0.15.1' end ŲϬʢȰοƜȁ̛̫΀Ιó˟ҷ˜Ѝ΍ ̷– gem ̫˕ѽ ˼Ċѓϡ bundle install ůϪїA gem 96 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ $ bundle install ˼Ċ¶ţÔ GuardїʠŮȃιě RSpec гn̛ $ bundle exec guard init rspec Writing new Guardfile to /Users/mhartl/rails_projects/sample_app/Guardfile rspec guard added to Guardfile, feel free to edit it ˼ĊŸΠщ GuardfileїʠǃүǺ˜ЍěϱijɌõĊ Guard ȃιѓϡžư̫˜ЍìϮR̀ 3.35 R̀ 3.35 ʑәϻ Guardfile ̫R̀˕DZҺѸ̫ require require 'active_support/inflector' guard 'rspec', all_after_pass: false do . . . # Custom Rails Tutorial specs watch(%r{^app/controllers/(.+)_(controller)\.rb$}) do |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb", (m[1][/_pages/] ? "spec/requests/#{m[1]}_spec.rb" : "spec/requests/#{m[1].singularize}_pages_spec.rb")] end watch(%r{^app/views/(.+)/}) do |m| (m[1][/_pages/] ? "spec/requests/#{m[1]}_spec.rb" : "spec/requests/#{m[1].singularize}_pages_spec.rb") end watch(%r{^app/controllers/sessions_controller\.rb$}) do |m| "spec/requests/authentication_pages_spec.rb" end . . . end ҷїϡ guard 'rspec', all_after_pass: false do ͆wŗХ̫˜ЍѫѐĊ Guard _ѓϡȁɽ̫˜Ѝ$5ÊǕ“ѯΆõΝѿʐ”ѐ͘ ̓ĴǻUþTѓϡҷ̫ĚSđÌ guard 5 97 $ bundle exec guard Šʔlǯъ‘ĚSÀҷ̫ bundle execҲϬȧ˽ 3.6.1 ω KΑ̫ŹјϡІΦ ҼtЗ Šʔ Guard ȼ͈Σƅ spec/routing ̴DŽlþTµƶ ̫͝ɘVřʌyʵїҌЕ $ mkdir spec/routing 3.6.3 -ö Spork Lśæŀ ѓϡ bundle exec rspec ɩlǼЄƝΒżϳ»5ĴƷţѓϡ˜Ѝ*Àɽş©͓̫ƒҿɩҖ ɦ˜ЍƷţƊ _NjǕŰǺїɮĭ$ʿʭ RSpec ѓϡ˜ЍɩѹϬѿɞÊцɗ Rails ̒ŇSpork ˜ЍɿËĩ11þTϵ¤їҕ ӄSpork üÊц ʭ̒Ň˼Ċ_$ĊΛ̫˜ЍΜȓ ј͘ˉSpork Δć GuardìϮ 3.6.2 ωn̛Ɗɹǁ œ5 ӊϬȏ spork ʑ GemfileìϮR̀ 3.36 R̀ 3.36 ͈o͘Ʈ̫ Gemfile source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' group :development, :test do . . . gem 'spork-rails', github: 'railstutorial/spork-rails' gem 'guard-spork', '1.5.0' gem 'childprocess', '0.3.6' end . . . ѝR̀n̛5҂žʄɓ͘yɌ̫ spork-rails̴̫ɮ›Ź Rails 4ơʀTĊŸҲϬn̛їyɌ̫̂ ʄИҩɩ–˕ВѸ¯Ź˼Ċѓϡ bundle install ůϪ Spork $ bundle install ȷʌƀ‘ Spork ̫ІΦ $ bundle exec spork --bootstrap 11. Spork ɮ spoon-fork ̫ćǺЋїһ̴̫ĉŪ*ȁTý‚ Spork 0ɮó POSIX forks ̫ð– 98 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ̓ĴǻUϬyɌĉ$ spec/spec_helper.rb ̫ RSpec ІΦɘVϽȁҲ̫̒ŇĴ Ӏ˙̚preforkR̀Ļ ÊцїʠȃιwЈ̒ŇüϧÊц ʭìϮR̀ 3.37 R̀ 3.37 ƃ̒ŇÊцR̀ʑ Spork.prefork R̀Ļ spec/spec_helper.rb require 'rubygems' require 'spork' Spork.prefork do ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' require 'rspec/autorun' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} # Checks for pending migrations before tests are run. # If you are not using ActiveRecord, you can remove this line. ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration) RSpec.configure do |config| # ## Mock Framework # # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: # # config.mock_with :mocha # config.mock_with :flexmock # config.mock_with :rr # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false # instead of true. config.use_transactional_fixtures = true # If true, the base class of anonymous controllers will be inferred # automatically. This will be the default behavior in future versions of # rspec-rails. config.infer_base_class_for_anonymous_controllers = false # Run specs in random order to surface order dependencies. If you find an 99 # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = "random" config.include Capybara::DSL end end Spork.each_run do # This code will be run each time you run your specs. end ѓϡ Spork *ÀǻUþTѓϡҷ̫ϹɩĚS$˜ЍɩҖ̫ȼӑȌ Ѧ $ time bundle exec rspec spec/requests/static_pages_spec.rb ...... 6 examples, 0 failures real user sys 0m8.633s 0m7.240s 0m1.068s ǻU̺»˜Ѝ΍V̛5дѐ 7 ͓̫ɩҖ˜Ѝʄс0̛5дѐ 0.1 ͓$5ÊѬїѐ͘ǻUþTȄƷ Ғ ̫ĚSϡ͠øј‘ư̛͘Ʈ̫ʢ̴DŽ˼ĊđÌ Spork ɿËĩ $ bundle exec spork Using RSpec Loading Spork.prefork block... Spork is ready and listening on 8989! Šʔǯъ‘ĚSÀҷ̫ bundle execИì˽ 3.6.1 ω ̫ŹĴû ĚSϡ͠ø ѓϡ˜Ѝ΍V ƫȦŲ --drbdistributed Ruby¯ƞƻ RubyѥһӎЈ ̒Ň̫ÊцɩҖɮčɪɯ̫§ƅ5 $ time bundle exec rspec spec/requests/static_pages_spec.rb --drb ...... 6 examples, 0 failures real 0m2.649s user 0m1.259s sys 0m0.258s 100 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ʿʭѓϡ rspec ѹϬȦŲ -drb ѥһɽ˸Ӗ˻ȁTǻƶϿƃ˜Ê‘ư̛͘Ʈʢ̴DŽ̫ .rspec ɘV ŠR ̀ 3.38 ȁ͈ R̀ 3.38 ІΦ RSpec Ͻ˜οÌn̛ Spork .rspec --colour --drb n̛ Spork ɩ̫ ˸Зɪ yɌŰӀ˙̚R̀Ļ Óď̫ɘVĊoŠ routes.rblϬѿđ Spork ɿËĩϽŮ ѿɞÊц Rails ̒ŇŠʔ˜ЍŗХ5ήlϳnjŮưВɮѫѐ̫þTn̛ Ctrl-C Ѡ¬˼Ċѿđ Spork $ bundle exec spork Using RSpec Loading Spork.prefork block... Spork is ready and listening on 8989! ^C $ bundle exec spork Guard h Spork Q, Spork ě Guard гn̛ɩ_NjǁœǻUþTn̛Š̫ĚSІΦ $ bundle exec guard init spork ˼ĊǻUϬȧ˽R̀ 3.39 ȁ͈̫ŹyɌ Guardfile R̀ 3.39 $n̛ Spork ήyɌ̫ Guardfile require 'active_support/inflector' guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do watch('config/application.rb') watch('config/environment.rb') watch('config/environments/test.rb') watch(%r{^config/initializers/.+\.rb$}) watch('Gemfile') watch('Gemfile.lock') watch('spec/spec_helper.rb') { :rspec } watch('test/test_helper.rb') { :test_unit } watch(%r{features/support/}) { :cucumber } end guard 'rspec', after_all_pass: false, cli: '--drb' do . . 101 . end ˕DZǻUyɌ5 guard ̫ìɕÓď5 cli: '--drb'їþT͆w Guard ɮĴ Spork ɿËĩ̫ĚSϡ̠ҷ Command-line Interface, cli ѓϡ̫ǻUіÊ‘5̯ϱ features/support/ ̴DŽ̫ĚSї̴DŽ_Mͩ 5 ͥƷţ̯ϱ yɌŰ*ĊǻUƊþTѫѐ guard ĚSĈɩđÌ Guard ě Spork 5 $ bundle exec guard Guard _οÌđÌ Spork ɿËĩœœ§ƅ5ʿʭѓϡ˜Ѝ̫ɩҖ ѺΦ5 GuardSporkěþѥ̫˜Ѝѫ̫̾˜Ѝ̒Ň_Ͻ˜ЍӌÌƷò̫ѐ͘õnjɽжϽGˋ˭˜ ɹ՝ ŹИϯ̺ʄ2̫ѺŝϱӃ 3.6.4 o Sublime Text Ŕĭæŀ Šʔln̛ Sublime Text ̫ЏŮɽ Aǁœ̫ĚSþTĴΠщĩ ̶ȷѓϡ˜Ѝїɮǻ̴Àn̛̫ɟƻĴ˜ ЍNjƅɩѓk̷̫ǃşåtɮ̆œľ̫˜Ѝϥ̓0ҌŠʔϬn̛їÉιlϬìά Sublime Text 2 Ruby ˜ Ѝ ҂žlȁ̛΀Ι̫ЗɪјϡІΦĴǻ̫΀Ι Mac OS XǻþTȧ˽ҷ̫ɟ˓ůϪȁҲ̫ĚS $ cd ~/Library/Application\ Support/Sublime\ Text\ 2/Packages $ git clone https://github.com/maltize/sublime-text-2-ruby-tests.git RubyTest їɩlǼЄ0ǯȧ˽ Rails ɓ͘ Sublime Text ̫ЗɪІΦ  ѿđ Sublime TextRubyTest Óȼp5Š̫ĚS • Command-Shift-R ѓϡÞ ̫˜ЍŠʔĴ it Ļ ѓϡǼέ ΍˜ЍŠʔĴ describe Ļ ѓ ϡ • Command-Shift-E ѓϡ ʭѓϡ̫˜Ѝ • Command-Shift-T ѓϡǃÀɘV ̫ȁɽ˜Ѝ ĭ$ånɮ Ƅľһ̴̫˜Ѝ0þι_ϊЫNjŐɩҖȁTþTÞ̫̌ѓϡ ˜ЍǼ Ƅ΍˜ЍƊþTω ̹NjŐ̫ɩҖåtɮÞ ̫˜Ѝ0ϬӀÊц Rails ̒ŇȁTїAĚSɼşɮĴ Spork ѓϡ ѓϡÞ ̫˜Ѝ §ƅ5ѓϡɗ˜ЍɘV̫ɩҖŸѓϡ Spork іþT§ƅđ̘Ѝ̒Ň̫ɩҖҷɮǻȹϐ̫ɈkҼƮ 1. Ĵ ĚSϡ͠ø đÌ Spork 2. Π¢ ˜ЍǼ Ƅ΍˜Ѝ 3. Ȇϡ Command-Shift-R ĚSʙ̺˜ЍǼ˜Ѝ΍ɮč$Άχ 4. Π¢̷ư̫͘ƮR̀ 5. Ȇϡ Command-Shift-E Ÿʭѓϡ´ȃ̫˜Ѝʙ̺˜ЍɮčõǺΝχ5 6. ŠʔҲϬѿŎͩ 2-5 ʷ 7. ŰǺ XËĊĴȼB*ÀĴĚSϡ ѓϡ rspec spec/ ͆w’Ѹ̫˜ЍLɮΝχ̫ 102 ͩ 3 ͥ ŃʄҴǙ̫ҹҷ ånlþTĴ Sublime Text ѓϡ˜Ѝɽɩǻіɮ_ѥȟn̛ GuardTƊɮǻϬKΑ̫ǻΒƤn̛̫ TDD Ȏ ʅ 103 ĉ 4 ć Rails Ħcû Ruby ɽ5ͩ 3 ͥ ̫oũ‚҇Ŀʄͥƃ$lKΑ Až Rails ʌЗNjѿϬ̫ Ruby ̾ЉRuby ДϷ̫̾Љ˸NjŐ ѐž  Rails ƷòέήϷҲϬȴȾ̫NjƅǻUѼ̛̫ɮɽº:Ƥϰ̫ Ruby ŭ1ѐ͘ǻU̴̫ʜɮƷòÌǙ̫ Web ư̛͘ƮȁTǻƶϿlŭ1 RailsĴїѐ͘ ŭ1 A Ruby ̾ЉŠʔϬǺ$  Rails ŸlƊ Ϭɹˤ‘̫ȴȾ Ruby 5ʄ2_$lĴǺ$Ÿ̫мѩŞŲ ļų̫Ń̈́Š 1.1.1 ω Зѐ̫ЙŰʄ2Ċ ǻƶϿlҘЙ ʄҒ҂ž Ruby ̫2oŠRuby ‘ҒThe Well-Grounded RubyistǼRuby *ѱ ʄͥKΑ5Nj՝Źͩ ѰҘЙˎɽȴȾ’ѸɮþT̕ϵ̫ĴĊΛ̫ͥωǻ_ΒƤȼ»ʄ̫ͥŹ 4.1 ‹Ķ M ͥǻUþT̺»ånǷXhηĊ̛»̫ Ruby ДϷǻU0þTµƶ  Rails ư̛͘ƮӐʖ0þTј ϡ˜ЍѐǻUqЯ̫ɮʄɓ͘ ȼp̫˜ЍR̀nj»ҌЕxǠ˼ĊϽ˜ѫѐǻUιǟɮїʠ‚ȁT ї ͥǻUϬɵºΤͤƷòŭ1ʵϱǻU̫ Ruby ̿ε ʭȷ϶ư̛͘ƮɩǻUƝΒn̛ Rails ƞƎëȳ5©+ɮҴǙ̫ҹҷ ̫R̀ѿŎìϮR̀ 4.1їʼR̀Ɗ ɮѿɞȵ̂ R̀ 3.26 R̀ 4.1 ͈o͘Ʈ̫ΤͤƞƎ app/views/layouts/application.html.erb Ruby on Rails Tutorial Sample App | <%= yield(:title) %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> <%= yield %> ϽǻUȏ˕DZÇү ĴR̀ 4.1 ̫ї ϡ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> 104 ͩ 4 ͥ Rails ηĊ̫ Ruby їϡR̀n̛ Rails Φ̫ɟ˓ stylesheet_link_tagɹ՝ŹИʙ̺ Rails API ɘʦ$ȁɽ̫ŨKͶľƼ ‘5 application.cssž:Βӎ!Ż̫ Rails ƷòέʌЗї ϡNjͮÞcɮїѾæπƅÓď5įǩ̽l̫ ī Ruby ̾Љ˸ Φ̫ Rails ɟ˓̛ȠĂ̫ɟ˓Л̛Symbol ě Hashї©˸ʄͥѹ_KΑ Ҧ5ȼpNj՝Φ̫ɟ˓pǻUĴϱij n̛*ŏRails іŠЄǻUοϡµƶοϡµƶ̫їAɟ˓ý‚ƣÍɟ˓ helperϬЗɪŠhοϡµƶ ƣÍɟ˓ǻUϬʌ̺̺R̀ 4.1 ʜӄѶ ϡ Ruby on Rails Tutorial Sample App | <%= yield(:title) %> їϡR̀qЯ:ʿϱij Ų)̫ҹҷʜӄn̛ provideoŠ <% provide(:title, 'Home') %>

Sample App

This is the home page for the Ruby on Rails Tutorial sample application.

Ѷ(ŠʔǻUȼpʜӄ_ǚʠĖ ǻU̫ʜӄ υѹÓď “•Ѹ¯Šʔǯɹ™gAƊϬÊ õÌ̫Ѹ ¯5ǻUĴƞƎ ̛5ƄȎƚŃʄƝΒų̓5їʠ̫ʜӄŠʔǻU·Ҧϱij ̫ provide ɟ˓Л̛ ъ¬̫ʜӄƊˎɽ5õÌ̫ѶѸ¯ Ruby on Rails Tutorial Sample App | “•Ѹ¯ƝΒъ¬5ήĊҷіɽ ͣʊ | $5ϵ¤їʜӄҕӄǻU_οŲ) ƣÍɟ˓ý‚ full_titleŠʔϱij ˎɽŲ)ʜӄ full_title _ѕĬʜӄ̫“•Ѹ¯å“Ruby on Rails Tutorial Sample App” ŠʔŲ)5³_Ĵ“•Ѹ¯Ċҷ Ê ͣʊ˼ĊŸȷВҹҷ̫ʜӄŠR̀ 4.21 R̀ 4.2 Ų) full_title ƣÍɟ˓ app/helpers/application_helper.rb module ApplicationHelper # Returns the full title on a per-page basis. def full_title(page_title) base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? base_title else "#{base_title} | #{page_title}" 1. ŠʔƣÍ®ɕɮ҂žʗ̆Ųȸ¼ĩ̫lưВȏŮɎјВȸ¼ĩ̷ư̫ƣÍɘV oŠ$ StaticPages ȸ¼ĩµƶ̫ƣ Í®ɕ υɎĴ app/helper/static_pages_helper.rb Ĵїoũ ǻU_ȏ full_title їƣÍ®ɕ̛ĴΤ ͤȁɽ̫Τҹ ҂žї͑ǧ¥ Rails ȼp5 ̆º̫ɘV app/helper/application_helper.rb 105 end end end ̓ĴǻUƝΒŲ)5 ƣÍɟ˓ǻUþT̛ŮʌͮÔƞƎƃ Ruby on Rails Tutorial Sample App | <%= yield(:title) %> ɻȮǺ <%= full_title(yield(:title)) %> ŠR̀ 4.3 ȁ͈ R̀ 4.3 ͈o͘Ʈ̫ΤͤƞƎ app/views/layouts/application.html.erb <%= full_title(yield(:title)) %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> <%= yield %> $5ϽїƣÍɟ˓гk̛ǻUϬĴ“ӊҹ”ϱij ƃǐϬ̫“Home”їЋ·ȳϽʜӄüw̢“•Ѹ¯ӊ ǻUϬȧ˽R̀ 4.4 ̫Źɹɞ̓ɽ̫˜ЍňÊžˎÓď 'Home' ̫ʜӄ˜Ѝ R̀ 4.4 ɹɞ“ӊҹ”ʜӄ̫˜Ѝ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do describe "Home page" do it "should have the content 'Sample App'" do visit '/static_pages/home' expect(page).to have_content('Sample App') end 106 ͩ 4 ͥ Rails ηĊ̫ Ruby it "should have the base title" do visit '/static_pages/home' expect(page).to have_title("Ruby on Rails Tutorial Sample App") end it "should not have a custom page title" do visit '/static_pages/home' expect(page).not_to have_title('| Home') end end . . . end ЍЍ̺lιč̎»$H(ǻU˦Ê5 ɞ˜Ѝήɮ̶ȷyɌ*À̫˜Ѝȼ͈ ͫʥĴ 3.3.1 ω  ѓϡ˜Ѝʙ̺ɮčɽ ˜ЍŗХ5 $ bundle exec rspec spec/requests/static_pages_spec.rb $5Ͻ˜ЍѫѐǻUϬƃ“ӊҹ”ϱij ̫ provide Ѷϡ·ҦŠR̀ 4.5 ȁ͈ R̀ 4.5 ·ҦʜӄŲ)Ċ̫“ӊҹ” app/views/static_pages/home.html.erb

Sample App

This is the home page for the Ruby on Rails Tutorial sample application.

̓Ĵ˜ЍưВþTѫѐ5 $ bundle exec rspec spec/requests/static_pages_spec.rb ěƼ‘ư̛͘ƮʠƻϥѶϡR̀ ʠR̀ 4.2 ̫ŹžΒӎ!Ż̫ Rails ƷòέʌЗ̺гʌNjͮÞcɮŒ˯5Nj Ő_ϽGįǩ̫ Ruby ̾Љ module˕ѽƎѸõҀ̫Э~ƞƆ~˚͘ȸ¼Ūͨ"Ƚ~іɽѕĬ~ї ͥ0_KΑїA̾Љ 107 4.2 ĈhÌä ŭ1 Ruby ǻU%Ϭn̛̫Ƙ™ɮ Rails ȸ¼ÿŮɮ̛ʌě Rails ư̛͘ƮB=̫ĚSϡĴ 2.3.3 ω KΑѐї ȸ¼ÿɮŃ: Ruby ̫B=͘ƮirbƷò̫ĭʶ0Ɗιn̛ Ruby ДϷ̫’ѸÉιĴ 4.4.4 ω _K Αȸ¼ÿіþTј‘ Rails ̒Ňn̛ҷ̫ɟ˓ĴĚSϡ đÌȸ¼ÿ $ rails console Loading development environment >> әϻǧ¥ȸ¼ÿɮTƷò̒Ňđ̛̫їɮ Rails Ų)̫̫̌̒͢Ň* ˜Pɮ˜Ѝ̒Ňě̚C̒ Ň̒Ň̫׺ĴʄͥіҲϬ̾ѱǻU_Ĵ 7.1.1 ω ɹГΎ̫KΑ ȸ¼ÿɮNjş̫ŭ1Ƙ™l̛ɽȁ̡ǫƌǧ̫n̛ĎˎǐϬȘǏl©+_͂ĺXhϫŠʔl Ĵȸ¼ÿ ѯ»ҕӄ5þTn̛ Ctrl-C ΔʉǃÀȆϡ̫ĚSǼέn̛ Ctrl-D ̶ȷѠ¬ȸ¼ÿĴҘЙʄͥĊҷ̫ Źɩl_ò̓ʙҘ Ruby API _Njɽ̛API ÓďNjŐxǠoŠŠʔlǯʙ̺–: Ruby Ūͨ"ɹŐ̫ ŹþTʙ̺˜ ̫ String Ͷҹҷ 4.2.1 åš Ruby ̫˕ѽT?Ă #0ý“Hask Mark”ǼέɹЎDZ̫ý“ɔ²Ū‹”ƷŘ ̶»ϡƍΔʉRuby _Ụ̈́˕ ѽcɮ˕ѽžR̀ҘЙέÓȠR̫̀µkέæNjɽ̛Ĵҷ̫R̀ # Returns the full title on a per-page basis. def full_title(page_title) . . . end ͩ ϡƊɮ˕ѽЗɪ5Ċҷɟ˓̫k̛ υɣҲĴȸ¼ÿ ¢˕ѽѐ$5ЗɪR̀ǻ_ȧ˽ҷ̫DžƻÊ˕ѽoŠ $ rails console >> 17 + 42 # Integer addition => 59 Ĵʄω̫ҘЙѐ͘ Ĵȸ¼ÿ ъ‘ǼέŎ¼͹ЪĚSɩŠʔǴDZlþTŎ¼˕ѽñʵȸ¼ÿ_Ụ̈́˕ ѽ 108 ͩ 4 ͥ Rails ηĊ̫ Ruby 4.2.2 Ĉ Ūͨ"ͯɮ Web ư̛͘Ʈ ɼɽ̛̫ɕȰΔʐ5ĭ$Τҹ̫ŹƊɮMɕȰƯòѡ»˝ϲĩ̫Ūͨ"ǻUĴ ȸ¼ÿ gӎ Ūͨ"їʭǻUn̛ rails c đÌȸ¼ÿїɮ rails console ̫ͮ¢Džƻ $ rails c >> "" => "" >> "foo" => "foo" # ͝Ūͨ" # ҵ̫͝Ūͨ" ҷ̫Ūͨ"ɮŪҷҀŪҷҀŪͨ"literal stringѫѐðƼĂ"µƶȸ¼ÿĬɯ̫ɮʿ ϡ̫ϹͯΔ ʔʄo Ūͨ"ŪҷҀ̫ΔʔƊɮŪͨ"ʄс ǻUіþTn̛ + ĂћȷŪͨ" >> "foo" + "bar" => "foobar" # Ūͨ"ћȷ "foo" ћȷ "bar" ̫ѓϡΔʔɮŪͨ" "foobar"2 ûŏ ͑µƶŪͨ"̫ɟƻɮѫѐ ̆ʻ̫ú˓#{}јϡȽ~Ɉk 3 >> first_name = "Michael" => "Michael" >> "#{first_name} Hartl" => "Michael Hartl" # õҀЭ~ # Ūͨ"Ƚ~ ǻUȏ“Michael”Э~ΖõҀ first_name˼Ċƃ˜Ƚ‘»Ūͨ" "#{first_name} Hartl" ǻUþT ƃŪͨ"ѹЭ~ΖõҀ >> first_name = "Michael" => "Michael" >> last_name = "Hartl" => "Hartl" >> first_name + " " + last_name => "Michael Hartl" >> "#{first_name} #{last_name}" => "Michael Hartl" # Ūͨ"ћȷ ҖÊ5͝ʣ # k̷̛Ĉ̫Ƚ~ ˕DZϥэƻ̫Δʔɮ̷Ĉ̫ѐǻċn̛Ƚ~̫ɟƻĴŪͨ" ʑ ͝ʣ" "ɯnjNjº ȉ 2. –:“foo”ě“bar”Tîŕ̷–̫“foobar”ě“FUBAR”̫гˬИʙ̺ Jargon File KΑ“foo”̫ɘͥ 3. ˾ǣ Perl Ǽ PHP ̫Π͘GĕþTȏїÉιοÌȽ~Ψ‹ͨĂƷŘ̫õҀ̷žưoŠ "foo $bar" 109 ±TĈ ȄãŪͨ"ɼƤ̛̫ Ruby ɟ˓ɮ putsЙk“put ess”DZǜɮ“ȄãŪͨ"” >> puts "foo" foo => nil # ȄãŪͨ" puts ɟ˓іɽ Åk̛side-effect puts "foo" ӊ_ƃŪͨ"Ȅã»ƑƧ˼ĊŸѕĬ͝~ŪҷҀ nil ɮ Ruby ̫“H(ѹˎɽ”Ċ˝Ź $5ϡɘͮ˖ǻ_̹̣ => nil puts ɟ˓_οÌĴъ¬̫Ūͨ"ĊҷʑȮϡͨ \nÉιͶb̫ print ɟ˓³_ >> print "foo" foo=> nil >> print "foo\n" => nil # ȄãŪͨ"ě puts Ͷbcˎɽ˦ÊȮϡͨ # ě puts "foo" ʠ R¢_Ĉ ̴ÀKΑ̫oũѹɮn̛ðƼõƶ̫Ūͨ"ѐ Ruby 0Ɋȥ̛ÞƼõƶŪͨ"œŐɕǧ¥ї͑Ūͨ "̫ɐʔɮ ʠ̫ >> 'foo' => "foo" >> 'foo' + 'bar' => "foobar" # ÞƼõƶ̫Ūͨ" ѐ͑ɟ˓іɮɽNjѿϬ̫׺ Ruby _žÞƼĂŪͨ"јϡȽ~Ɉk >> '#{foo} bar' => "\#{foo} bar" # ÞƼĂŪͨ"ιјϡȽ~Ɉk ˕DZȸ¼ÿɮŠhn̛ðƼĂѕĬΔʔ̫ҲϬn̛ñɚ΋т)̆ʻŪͨoŠ # ŠʔðƼĂŪͨ"þT‚ÞƼĂȁ‚̫ȁɽ8ήіιјϡȽ~Ѷ(ÞƼĂŪͨ"ūĴ̫DZ)ɮH(Ė ÞƼ ĂŪͨ"̛̫ŌĴ:ŮU̻̫ƊɮŪҷ~üÓďlъ‘̫ŪͨoŠñɚ΋ĴNjŐ΀Ι ѹNj̆ʻƊˆȮϡ ͨ\n ʠŠʔɽ õҀҲϬÓď ñɚ΋n̛ÞƼĂƊNjͮÞ >> '\n' => "\\n" # ñɚ΋ě n Ūҷ~ ěÀo̫ # Ūͨ ʠRuby Ϭn̛ ӆŏ̫ñɚ΋ʌт)ñɚ΋ĴðƼĂŪͨ" Ϭϥэ ñɚ΋ƊϬ n̛ñɚ΋žͮÞ̫oũʌЗї̹5Őƅ8ѐŠʔɽNjŐҲϬт)̫ŪͨƊɯnj¬Ů̫k̛5 110 ͩ 4 ͥ Rails ηĊ̫ Ruby >> 'Newlines (\n) and tabs (\t) both use the backslash character \.' => "Newlines (\\n) and tabs (\\t) both use the backslash character \\." 4.2.3 ŠŇWd;*řè« Ruby °̬žПÓȠŪͨ"ě nil ѹɮǻU_Ĵ 4.4.2 ωKΑžПȎʅƏҷ̫DZ)ѐ υNjҭѫѐҘ Й ʄ2Ɗ̕ϵžПlϬŐ̺ Aoũȃιƶ͢žžП̫dzǝϻЉ ѐЗ¬žП̫k̛ƊNjͮÞ ŮþTĞư˟ǠoŠ Ūͨ"žПþTĞư length ї˟ǠŮѕĬŪͨ "Óď̫ŪͨɕҀ >> "foobar".length => 6 # ȏ length ˟Ǡ`ѨΖŪͨ" їʠ`ѨΖžП̫˟Ǡý‚ɟ˓ŮɮĴžП Ų)̫®ɕ4Ūͨ"іþTĞư empty? ɟ˓ >> "foobar".empty? => false >> "".empty? => true ˕DZ empty? ɟ˓ʃƍ̫ҕĂїɮ Ruby ̫ ·ŲЗɪɟ˓̫ѕĬ~ɮƞƆ~ true Ǽ falseƞƆ~Ĵ ˚͘ȸ¼ ̆ºɽ̛ >> s = "foobar" >> if s.empty? >> "The string is empty" >> else >> "The string is nonempty" >> end => "The string is nonempty" ƞƆ~іþTn̛ &&ě||Ǽě !ҵɈkͨΔćn̛ >> x = "foo" => "foo" >> y = "" => "" >> puts "Both strings are empty" if x.empty? && y.empty? => nil >> puts "One of the strings is empty" if x.empty? || y.empty? 4. NjȕʳʄͥĴ®ɕěɟ˓*ҖҩDZ̫ʌĬn̛Ĵ Ruby ї9έɮĈ ʫǖ ȁɽ̫ɟ˓ѹɮ®ɕȁɽ̫®ɕ0ѹɮɟ ˓ĭ$ °̬žП 111 "One of the strings is empty" => nil >> puts "x is not empty" if !x.empty? "x is not empty" => nil ĭ$ Ruby ̫ °ѹɮžПѶ( nil 0ɮžПȁTŮ0þTĞưɟ˓&oũto_s ɟ˓ŃʄþTȏ XhžПтȮǺŪͨ" >> nil.to_s => "" Δʔɯ˼ɮ͝Ūͨ"ǻUþTѫѐҷ̫ɟ˓"γchainӎЈї ˸ >> nil.empty? NoMethodError: You have a nil object when you didn\'t expect it! You might have expected an instance of Array. The error occurred while evaluating nil.empty? >> nil.to_s.empty? # ˟Ǡ"γ => true ǻU̺»nil žПʄсɣ˓Ğư empty? ɟ˓cɮ nil.to_s þT ɽ ̆ʻ̫ɟ˓þT˜ЍžПɮč$͝lưВι̎»їɟ˓ >> "foo".nil? => false >> "".nil? => false >> nil.nil? => true ҷ̫R̀ puts "x is not empty" if !x.empty? Зɪ5–ҎЋ if ̫û ̛͑˓ lþTΠ¢ ǃüǃ if Ċҷ̫ϥэƻ$̻ɩȃȆϡ̫Дúžư̫–ҎЋ unless 0þTї(̛ >> string = "foobar" >> puts "The string '#{string}' is nonempty." unless string.empty? The string 'foobar' is nonempty. => nil ǻUҲϬ˕DZ  nil ̫̆ʻǝҦ5 false ʄс*ŏȁɽ̫ Ruby žП Ůɮġ ƞƆ~$“€”̫ 112 ͩ 4 ͥ Rails ηĊ̫ Ruby >> if nil >> true >> else >> false >> end => false # nil ɮ€~ Ńʄȁɽ˜P̫ Ruby žПѹɮ“̻”̫ÓȠ 0 >> if 0 >> true >> else >> false >> end => true # 0Ҧ5 nil ě false *ŏ̫ °žПɮ̻~ 4.2.4 †Ìä Ĵȸ¼ÿ ǻUþTˆŲ) home ÌkR̀ 3.6ě full_title ƣÍɟ˓R̀ 4.2 ʠјϡɟ˓Ų) Ĵȸ¼ÿ Ų)ɟ˓ɽ˸Ӗ˻ǻU υ_ĴɘV Ų)ѐ̛ʌ˲͈іϡoŠǻUϬŲ) ĉ$ string_message ̫ɟ˓þTȷô ìɕѕĬ~ó¤:ìɕɮč$͝ >> def string_message(string) >> if string.empty? >> "It's an empty string!" >> else >> "The string is nonempty." >> end >> end => nil >> puts string_message("") It\'s an empty string! >> puts string_message("foobar") The string is nonempty. ˕DZ Ruby ɟ˓_ҵɯƻ̫ѕĬ~ ѕĬɼĊ Дú̫~Ĵҷ̫їoũ ѕĬ̫~_ʢȰìɕɮč$͝ ήѕĬŪͨ" ̫ Ruby 0Ɋȥɯƻ̫ȦŲѕĬ~ҷ̫R̀ěҷ̫ɐʔ ʠ >> def string_message(string) >> return "It's an empty string!" if string.empty? >> return "The string is nonempty." >> end 113 ΎǏ̫Йέþι_ò̓˜ųїѾͩ9 return ɮǐҽ̫k$ɟ˓̫ɼĊ ϥэƻͰɽˎɽ return Ūͨ" "The string is nonempty." ѹ_k$ѕĬ~ѐŌѹÊ return ̺гʌɹş̺ 4.2.5 lŵ Ûŷû˜NÌä ҷǻUʌ̕ϵ R̀ 4.2 ̫ full_title ƣÍɟ˓ 5 module ApplicationHelper # ʢȰȁĴҹҷѕĬŰɗ̫ʜӄ # Ĵɘʦ ɯ͈̫˕ѽ def full_title(page_title) # ɟ˓Ų) base_title = "Ruby on Rails Tutorial Sample App" # õҀЭ~ if page_title.empty? # ƞƆ˜Ѝ base_title # ҵɯƻѕĬ~ else "#{base_title} | #{page_title}" # Ūͨ"Ƚ~ end end end ɟ˓Ų)õҀЭ~ƞƆ˜Ѝ˚͘ȸ¼ěŪͨ"Ƚ~——΍ćĴ гŲ)5 þTĴΤͤƞƎ n̛̫ƣÍ ɟ˓і̛»5 module ApplicationHelper module $ǻUȼp5 ͑ȏ̷–ɟ˓΍ΏĴ г̫ɟƻ͙Ċ ǻUþTn̛ include ȏŮȽ‘˜P̫Ͷ Π¢ υ̫ Ruby ͘ƮɩlϬοƜŲ)  module ˼ĊŸɯƻ̫ ƃ˜Ƽ‘Ͷ cɮž:ƣÍɟ˓ȁĴ̫ module ƊB̜ Rails ʌŌ̕Ƽ‘5ɼΐ̫Δʔɮ full_title ɟ˓ο Ì̫ƊþTĴȁɽ̫ϱij n̛5 4.3 ;#ûÇ·ďs ϝ˼ Web ͘Ʈ υѹɮŌ̕Ūͨ"c0ҲϬ˜P̫ɕȰͶľʌ̚ǺŪͨ"ʄωǻUƊʌKΑ AžƷò Rails ư̛͘ƮNjѿϬ̫ Ruby ̫˜PɕȰͶľ 4.3.1 Çėh Range ɕ΍Ɗɮ ΍ҼƮ̆Ų̫‹΁ʄ2ƈˎɽ̛ѐɕ΍ѐ̕ϵ5ɕ΍ƊιNjş̫̕ϵ Hash 4.3.3 ω0ɽ Í:̕ϵ Rails ̫ɕȰʬľoŠ 2.3.3 ω ̛»̫ has_many –γ10.1.3 ω_‚ГΎKΑ ̴ÀǻUƝΒϊ5NjŐ̫ɩҖ̕ϵŪͨ"MŪͨ"ѐ˩»ɕ΍þTM split ɟ˓Ʒţ >> "foo bar baz".split => ["foo", "bar", "baz"] # ȏŪͨ"¯ÆǺɽ‹΁̫ɕ΍ 5. ˜ųїѾіɽ ĵɟǻUіι̕ϵѶƊɮ Rails ɮǚ(ȏїAγ΀Ĵ г̫ ȏ URI ɭƂ»Ìkfull_title ƣÍ ®ɕþTĴϱij n̛ͪїɮNjɽDZǜ̫ЏӄǻƶϿlTĊşş̫5ϵ ѐn̛ Rails ƫҲϬے5ϵ Rails ̫ѓkʆ̕ϋǯɹˤ‘̫5ϵ RailsǻȹϐҘЙ Obie Fernandez ̫Rails 3 *ѱ 114 ͩ 4 ͥ Rails ηĊ̫ Ruby ѝR̫̀ѕĬΔʔɮ ɽ‹΁̫ɕ΍әϻǧ¥split Ĵ͝ʣŌȏŪͨ"¯ÆǺɕ΍ǃ˼l©+þ TĴXhĵɟјϡ¯Æ >> "fooxbarxbazx".split('x') => ["foo", "bar", "baz"] ě˜PΠ͘ДϷ̫1ǭ ʠRuby ɕ΍̫΂Ƽindex0ɮMұƷţ̫ɕ΍ ͩ ‹΁̫΂Ƽɮ 0ͩ9 ‹΁̫΂Ƽɮ 1qʶͶȹ >> a = [42, 8, 17] => [42, 8, 17] >> a[0] => 42 >> a[1] => 8 >> a[2] => 17 >> a[-1] => 17 # Ruby n̛ɟȠĂϓóɕ΍‹΁ # ΂ƼіþTɮТɕ ǻU̺»Ĵ Ruby ɮn̛ɟȠĂʌϓóɕ΍‹΁̫Ҧ5ї͑ɟ˓Ruby і$ AƤ̛̫‹΁ϓóɈkȼp5 ºĉsynonym 6 >> a => [42, 8, 17] >> a.first => 42 >> a.second => 8 >> a.last => 17 >> a.last == a[-1] => true # üɮ$5̺  a ̫~ɮH( # ̛ == јϡžˀ ɼĊ ϡKΑ5̷ͪˀчɈkͨ ==Ruby ě˜PДϷ ʠіȼp5žư̫ !=ͪͪ˜P̫Ɉkͨ >> x = a.length => 3 >> x == 3 => true >> x == 1 => false # ěŪͨ" ʠɕ΍0þTĞư length ɟ˓ 6. ҷR̀ n̛̫ second ɟ˓ɮ Ruby Ų)̫ήɮ Rails ˦Ê̫ĴїѾþTn̛їɟ˓ɮĭ$ Rails ȸ¼ÿ_οÌÊ ц Rails ž Ruby ̫Éιȇƒ 115 >> x != 1 => true >> x >= 1 => true >> x < 1 => false Ҧ5 lengthѝR̫̀ͩ ϡ*ŏɕ΍іþTĞư ń˜P̫ɟ˓ >> a => [42, 8, 17] >> a.sort => [8, 17, 42] >> a.reverse => [17, 8, 42] >> a.shuffle => [17, 42, 8] >> a => [42, 8, 17] ˕DZҷ̫ɟ˓ѹˎɽyɌ a ̫~ŠʔlǯyɌɕ΍̫~Ϭn̛žư̫“˷ǀbang”ɟ˓*ȁTї(ýɮ ĭ$їѾ̫dzĄĂΒƤѹЙk“bang” >> a => [42, 8, 17] >> a.sort! => [8, 17, 42] >> a => [8, 17, 42] lіþTn̛ push ɟ˓ċɕ΍ ˦ʋ΁Ǽέn̛ͪW̫ << Ɉkͨ >> a.push(6) # ȏ 6 Ê»ɕ΍Δƍ => [42, 8, 17, 6] >> a << 7 # ȏ 7 Ê»ɕ΍Δƍ => [42, 8, 17, 6, 7] >> a << "foo" << "bar" # "γɈk => [42, 8, 17, 6, 7, "foo", "bar"] ɼĊ oũЗɪlþTȏ˦ÊɈk"Ĵ гɈk Ĉɩ0ЗɪRuby ˆNj՘P̫ДϷɕ΍þTÓďĈͶ ľ̫ɕȰʄo ɮɕŪěŪͨ"˥ć ÀҷǻƯ split ȏŪͨ"¯ÆǺŪͨ"ǻUіþTn̛ join ɟ˓јϡ̷ñ̫Ɉk 116 ͩ 4 ͥ Rails ηĊ̫ Ruby >> a => [42, 8, 17, 7, "foo", "bar"] >> a.join # ˎɽћȷͨ => "428177foobar" >> a.join(', ') # ћȷͨɮ ѪĂě͝ʣ => "42, 8, 17, 7, foo, bar" ěɕ΍ɽ˸Ͷb̫ɮ Rangen̛ to_a ɟ˓ȏŮтȮǺɕ΍ǼЄɹş̕ϵ >> 0..9 => 0..9 >> 0..9.to_a # Ҍ5to_a Ĵ 9 Л̛5 NoMethodError: undefined method `to_a\' for 9:Fixnum >> (0..9).to_a # Л̛ to_a Ϭ̛ȠĂÓf Range => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ϝ˼ 0..9 ɮ ć˓̫ Rangeѐҷͩ9ϥэƻĔЊǻUЛ̛ɟ˓ɩϬÊȠĂ Range ΒƤϧ̛ʌϓó ΍ɕ΍‹΁ >> a = %w[foo bar baz quux] => ["foo", "bar", "baz", "quux"] >> a[0..2] => ["foo", "bar", "baz"] # %w µƶ ‹΁$Ūͨ"̫ɕ΍ Range 0þn̛Ūʾ >> ('a'..'e').to_a => ["a", "b", "c", "d", "e"] 4.3.2 r ɕ΍ě Range þTĞư̫ɟ˓ ɽNjŐѹþTк̽ Ļblockїɮ Ruby ɼǁœ0ɮɼҭ̕ϵ̫Éι >> (1..5).each { |i| puts 2 * i } 2 4 6 8 10 => 1..5 117 їR̀Ĵ Range (1..5) Л̛5 each ɟ˓˼Ċíȏ { |i| puts 2*i } їĻ`ѨΖ each ɟ˓|i| ь̫ͣʊĴ Ruby ú˓ ɮ̛ʌŲ)ĻõҀ̫üɽїɟ˓ȃ̾ѱŠhŌ̕Ċҷк̫̽Ļʄo Range ̫ each ɟ˓_Ō̕Ċҷ̫ĻĻ ɽ ʄĵõҀ ieach _ƃ Range ̫Ć~`јĻ ˼ĊȆϡ̷ư̫Ɉk ϊȠĂɮ ͑Ų)Ļ̫ɟ˓іɽû ͑ɟ˓þ̛ >> (1..5).each do |i| ?> puts 2 * i >> end 2 4 6 8 10 => 1..5 ĻþTŐ: ϡ0ΒƤɮŐ: ϡ̫ʄ2 ǻU_Ѵ˽ Ƥ̛̫·ŲǃĻüɽ ϡͮÞ̫R̀ɩn̛ϊȠ ĂDžƻ ǃĻɮ ϡNjґ̫R̀ǼέŐϡɩn̛ do..end Džƻ >> (1..5).each do |number| ?> puts 2 * number >> puts '--' >> end 2 -4 -6 -8 -10 -=> 1..5 ҷ̫R̛̀ number Rɻ5 iǻǯĔЊl̫ɮXhõҀĉѹþTn̛ ҦҵlƝΒɽ5 AΠ̾͘Љč³žĻ̫̕ϵɮˎɽȱlj̫lϬ‚̫ɮŐ̺̺njŐ5ɼĊlƊ_1ǭƯ̫̊ ˓57 ƬşGͶɇґ:Mųo ǂΊ¬ υǝҷɮ Aoũ˜ ©̛»5 map ɟ˓ >> 3.times { puts "Betelgeuse!" } "Betelgeuse!" "Betelgeuse!" "Betelgeuse!" # 3.times Ċк̫ĻˎɽõҀ 7. ĻɮҔÓclosure̾ѱї ˸žЬˤΠ͘Gĕþι_ɽ˸ƣÍҔÓɮ ͑Øĉ®ɕ˜ ҟƢ5 AɕȰ 118 ͩ 4 ͥ Rails ηĊ̫ Ruby => 3 >> (1..5).map { |i| i**2 } # ** ϥ͈ƥ => [1, 4, 9, 16, 25] >> %w[a b c] # ŸЗ %w þTµƶ‹΁$Ūͨ"̫ɕ΍ => ["a", "b", "c"] >> %w[a b c].map { |char| char.upcase } => ["A", "B", "C"] >> %w[A B C].map { |char| char.downcase } => ["a", "b", "c"] ҷ̫R̀Зɪmap ɟ˓ѕĬ̫ɮĴɕ΍Ǽ Range ̫ʿ‹΁ȆϡĻ R̀Ċ̫Δʔ ̓ĴǻUƊþTʌ̕ϵ ǻĴ 1.4.4 ω ̛ʌ̚Ǻҩʆ9ΈŁĉ̫Ѷϡ Ruby R̀5 ('a'..'z').to_a.shuffle[0..7].join ǻU ʷ ʷ¯ϵ  >> ('a'..'z').to_a # Ūʾϥɕ΍ => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] >> ('a'..'z').to_a.shuffle # Ȅ4ɕ΍ => ["c", "g", "l", "k", "h", "z", "s", "i", "n", "d", "y", "u", "t", "j", "q", "b", "r", "o", "f", "e", "w", "v", "m", "a", "x", "p"] >> ('a'..'z').to_a.shuffle[0..7] # ó¬Àҷ̫ 8 ‹΁ => ["f", "w", "i", "a", "h", "p", "c", "x"] >> ('a'..'z').to_a.shuffle[0..7].join # ƃó¬̫‹΁ćƫǺŪͨ" => "mznpybuj" 4.3.3 Hash h Symbol Hash ʄЧƊɮɕ΍üѐŮ̫΂ƼƎҤ:n̛ɕŪųҠĴ AДϷ ̆ºɮ Perlĭ$їêĭƊ ȏ Hash ý‚–γɕ΍associative arrayHash ̫΂ƼǼέý“Ҏ”©+þTɮXhžПoŠǻUþTn ̛Ūͨ"ǃҎ >> user = {} => {} >> user["first_name"] = "Michael" => "Michael" >> user["last_name"] = "Hartl" => "Hartl" >> user["first_name"] => "Michael" # {} ɮ ͝ Hash # Ҏ$ "first_name"~$ "Michael" # Ҏ$ "last_name"~$ "Hartl" # ϓó‹΁̫ɟƻͶbɕ΍ 119 >> user # Hash ̫ŪҷҀDžƻ => {"last_name"=>"Hartl", "first_name"=>"Michael"} Hash ѫѐ žϊȠĂ Óď AҎ~ž̫Džƻϥ͈üɽ žϊȠĂήˎɽҎ~ž{}Ɗɮ ͝ HashҲϬ ˕DZHash ̫ϊȠĂěĻ ̫ϊȠĂɮ ʫǖɮ̫їþι_ϽlўǩѐHash ϝ˼ěɕ΍Ͷ bcæɽ NjѿϬ̫׺ Hash ̫‹΁ˎɽ̆Ų̫ҼƮ8 ŠʔҼƮNjѿϬ̫ЏƊϬn̛ɕ΍5 ѫѐɟȠĂ̫DžƻʿʭŲ) ‹΁̫ɟƻŕɑȱn̛ => ¯ҫ̫Ҏ~žї͑ŪҷҀ̫DžƻŲ) Hash Ϭͮ˖nj ŐǻU͖Ċ ͑ɟƻ$“hashrocket” >> user = { "first_name" => "Michael", "last_name" => "Hartl" } => {"last_name"=>"Hartl", "first_name"=>"Michael"} Ĵҷ̫R̀ ǻ̛»5  Ruby ú˓·ŲĴƙϊȠĂĊҷěāϊȠĂÀҷʑ5 ͝ʣȸ¼ÿ_Ụ̈́ї A͝ʣϬҕǻ$H(їA͝ʣɮ·ŲvǺ̫ǼЄɮʗ Ruby Π͘œ̃ħʮї͑Džƻ˼Ċ·ŲƊC̚ 5 ̴À$ʴǻU̫Ҏ̛̫ѹɮŪͨ"cĴ Rails ̛ Symbol ǃҎæNjƤϮSymbol ̺гʌˆŪͨ"üѐˎɽ ÓďĴ žƼĂ ήɮĴÀҷÊ  ĂoŠ:name Ɗɮ  SymbollþTȏ Symbol ̺Ǻˎɽ·ʉ̫Ū ͨ" 9 >> "name".split('') => ["n", "a", "m", "e"] >> :name.split('') NoMethodError: undefined method `split' for :name:Symbol >> "foobar".reverse => "raboof" >> :foobar.reverse NoMethodError: undefined method `reverse' for :foobar:Symbol Symbol ɮ Ruby ̆ɽ̫ ɕȰͶľ˜PДϷNjƅ̛»¶̺гʌdzϳNjŚǞѐ Rails ΒƤ̛»ŮȁTl NjǕƊ_1ǭ̫ ̛ Symbol ǃҎǻUþTȧ˽Š̫ɟƻŲ)  user Hash >> user = { :name => "Michael Hartl", :email => "michael@example.com" } => {:name=>"Michael Hartl", :email=>"michael@example.com"} >> user[:name] # ϓó :name žư̫~ => "Michael Hartl" >> user[:password] # ϓó ʂŲ)̫Ҏžư̫~ => nil 8. Ĵ Ruby 1.9 ˜ų_ȧ˽‹΁ъ‘ɩ̫ҼƮwū HashѐqЯҼƮɯ˼ɮɪɴ̫ 9. ˎɽ5·ʉ̫şŌɮSymbol NjŹɫјϡˀчŪͨ"Ϭȧ˽Ūʾ  ̫ˀчή Symbol üҲјϡ ʭɈkїƊnnj Symbol Ǻ$ Hash Ҏ̫ɼmѥȟ 120 ͩ 4 ͥ Rails ηĊ̫ Ruby Mҷ̫oũǻUþT̺¬Hash ˎɽŲ)̫Ҏžư̫~ɮ nil ĭ$ Symbol ǃҎ̫ǧ¥ŕɱѰ5Ruby 1.9 ƨκƊ$ї͑ǧ¥Ų)5 ɞ̫ú˓ >> h1 = { :name => "Michael Hartl", :email => "michael@example.com" } => {:name=>"Michael Hartl", :email=>"michael@example.com"} >> h2 = { name: "Michael Hartl", email: "michael@example.com" } => {:name=>"Michael Hartl", :email=>"michael@example.com"} >> h1 == h2 => true ͩ9ĚSȏ hashrocket Džƻ̫Ҏ~žõǺ5ҎĊк̽  Ă˼ĊŸк̽ ~̫Džƻ { name: "Michael Hartl", email: "michael@example.com" } ї͑Δʐɹş̫ˑϨ5˜PДϷoŠ JavaScript Hash ̫ϥ̓ɟƻĴ Rails ͉× 0еʌеôʮђї͑ ɟƻ̓ĴѹĴn̛ȁTlϬιЉºŮU Hash ‹΁̫~þTɮXhžП̙πɮ  HashŠR̀ 4.6 ȁ͈ R̀ 4.6 Hash Ɩŝ >> params = {} # Ų) ĉ$ paramsparameters ̫͖̫ͮ Hash => {} >> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" } => {:name=>"Michael Hartl", :email=>"mhartl@example.com"} >> params => {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}} >> params[:user][:email] => "mhartl@example.com" ї͑ Hash ɽ Hash ̫DžƻǼ͖$ Hash ƖŝĴ Rails œҀ̫n̛ǻUM 7.3 ωƷţ_ȷ϶» ɕ΍ě Range ʠHash 0þTĞư each ɟ˓oŠ ĉ$ flash ̫ HashŮ̫ҎɮʋV¸ ɜ:success ě :error >> flash = { success: "It worked!", error: "It failed." } => {:success=>"It worked!", :error=>"It failed."} >> flash.each do |key, value| ?> puts "Key #{key.inspect} has value #{value.inspect}" >> end Key :success has value "It worked!" Key :error has value "It failed." ˕DZɕ΍̫ each ɟ˓Ċҷ̫Ļüɽ õҀή Hash ̫ each Ċҷ̫ĻȷôõҀkey ě valueȁT Hash ̫ each ɟ˓ʿʭѰèѹ_T Ҏ~ž$ŃʄÞdјϡ 121 ҷ̫͈o ̛»5Njɽ̛̫ inspect ɟ˓ѕĬϧЛ̛žП̫Ūͨ"ŪҷҀϥ̓Džƻ >> puts (1..5).to_a # ȏɕ΍k$Ūͨ"ъ¬ 1 2 3 4 5 >> puts (1..5).to_a.inspect # ъ¬ ɕ΍ŪҷҀDžƻ [1, 2, 3, 4, 5] >> puts :name, :name.inspect name :name >> puts "It worked!", "It worked!".inspect It worked! "It worked!" ҼtЗ ĭ$n̛ inspect ъ¬žП̫ɟƻΒƤn̛$ʶіɽ Ғ̫Ǖȱɟƻp ɟ˓ >> p :name :name # ͪW: puts :name.inspect 4.3.4 Ţë¢8 CSS û$ÿ ̓ĴǻUϬѿɞϻЉ R̀ 4.1 ĴƞƎ Ƽ‘ CSS ̫R̀ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> ǻU̓ĴŃʄþT̕ϵїϡR̀5Ĵ 4.1 ω ͮÞ̫ȼ»ѐRails Ų)5 ̆ʻ̫®ɕ̛ʌƼ‘ʠƻϥ ҷ̫R̀ stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true Ɗɮžї®ɕ̫Л̛ѐіɽ©ŚǞ̫ĵɟͩ ȠĂĠ‰ë5 ĭ$Ĵ Ruby ȠĂɮþT̹̣̫ ҷ̫ϡR̀ɮͪW̫ # Parentheses on function calls are optional. stylesheet_link_tag("application", media: "all", "data-turbolinks-track" => true) stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true 122 ͩ 4 ͥ Rails ηĊ̫ Ruby ͩ9media Ѹ¯ɯ˼ɮ  Hashcɮǚ(ˎ̛ϊȠĂ ĭ$ĴЛ̛®ɕɩŠʔ Hash ɮɼĊ ìɕŮ̫ ϊȠĂɮþT̹̣̫ҷ̫ϡR̀ɮͪW̫ # Curly braces on final hash arguments are optional. stylesheet_link_tag "application", { media: "all", "data-turbolinks-track" => true } stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true іɽ$H( data-turbolinks-track їҎ~žn̛ɧú˓ ĭ$Šʔɮɞɞú˓¢Ǻ data-turbolinks-track: true Ɗ_ƉЍµƶ  Symbol :data-turbolinks-trackcɮĭ$Óď5ћŪͨȁTї Symbol ɮć˓̫ ȁTƊüιn̛ɧú˓¢Ǻ "data-turbolinks-track" => true ɼĊ$H(ҷїϡR̀ stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true $H(þTї(¢ Җɽ͝ʣ0þT ǃ˼þTRuby –ǏɽˎɽȮϡ[^1-10]ǻ*ȁTȏR̀șǺϡɮ ϬwȥʿϡR̀дѐ 80 ²[^1-11] ȁTǻUƊ̺»5їʠ ϡR̀ stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true ŮЛ̛5 stylesheet_link_tag ®ɕ`јìɕ ɮŪͨ"Ȧɪʠƻϥ̫мlj û ɮ HashÓ ď‹΁ȦɪŨKͶľƫđ̛ Turbolink Éι(Rails 4 ̫ɞÉιʄ2̫ĊΛϏ͛_ˤ‘KΑ)ĭ$n̛̫ɮ <%= %>®ɕ̫ȆϡΔʔ_ѫѐ ERb Ƚ‘ʬʎ ŠʔlĴ˝ϲĩ ʙ̺Τҹ̫ˬR̀Ɗ_̺»Ƽ‘ʠƻϥȁ̛ ̫ HTMLìϮR̀ 4.7lþι_Ĵ CSS ̫ɘVĉĊ̺»ӆŏ̫ŪͨoŠ ?body=1їɮ Rails ʑ̫ þT͆w CSS yɌĊ˝ϲĩ_ѿɞÊцŮ R̀ 4.7 Ƽ‘ CSS ̫R̀̚Ǻ̫ HTML ŠʔlȄƷ http://localhost:3000/assets/application.css ʙ̺ CSS ̫Џ_ò̓ɮ̫͝Ҧ5 A˕ѽĴͩ 5 ͥ ǻU_̺KΑŠh˦Êʠƻ 123 4.4 Ruby ď ǻU*ÀƝΒЗѐ Ruby ̫ °ѹɮžПʄωǻUƊ_οƜŲ) AžПRuby ě˜PҷċžПobjectorientedΠ͘ДϷ ʠn̛Ͷʌ΍Ώɟ˓˼ĊųoÔinstantiateͶµƶžПŠʔl´ȷ϶ҷċžПΠ͘ їAѹbŔ2 υѶ(ϽǻUʌ̺ AųҠ̫oũĎ 4.4.1 ×Ŝk ǻU̺ѐNjŐoũn̛Ͷ¶ţÔžПѐіˎɽʵƻ̫¶ţÔѐoŠǻUn̛ ðƼöţÔ Ūͨ "ðƼĂɮŪͨ"̫Ūҷʐѭĩliteral constructor >> s = "foobar" => "foobar" >> s.class => String # n̛ðƼĂ̫Ūҷʐѭĩ ǻU̺»Ūͨ"þTĞư class ɟ˓ѕĬ̫ΔʔɮŪͨ"ȁƓ̫Ͷ Ҧ5n̛Ūҷʐѭĩ*ŏǻUіþTn̛ͪW̫™ĉʐѭĩnamed constructoråĴͶĉЛ̛ new ɟ ˓ 10 >> s = String.new("foobar") => "foobar" >> s.class => String >> s == "foobar" => true # Ūͨ"̫™ĉʐѭĩ ҷ̫R̀ěŪҷʐѭĩɮͪW̫üɮɹιϥ̓ǻU̫DZij ɕ΍ěŪͨ"Ͷb >> a = Array.new([1, 3, 2]) => [1, 3, 2] ѐ Hash ƊɽAĈ5ɕ΍̫ʐѭĩ Array.new þȷô þѥ̫ìɕȦɪɕ΍̫¶ţ~Hash.new þȷ ô ìɕȦɪ‹΁̫әϻ~ƊɮǃҎūĴɩѕĬ̫~ >> h = Hash.new => {} >> h[:foo] => nil >> h = Hash.new(0) # ЍijϓóūĴ̫Ҏ :foo žư̫~ # ІΦūĴ̫ҎѕĬ 0 ήɮ nil 10. ѕĬ̫Δʔþι̜: Ruby ̂ʄ̫ĈήɽȁĈїoũ€Іln̛̫ɮ Ruby 1.9.3 124 ͩ 4 ͥ Rails ηĊ̫ Ruby => {} >> h[:foo] => 0 ĴͶЛ̛̫ɟ˓Šʄo̫ newǻU͖*$Ͷɟ˓class methodĴͶЛ̛ new nj»̫ΔʔɮїͶ̫ žП0ý‚їͶ̫ųoinstanceĴųoЛ̛̫ɟ˓oŠ lengthý‚ųoɟ˓instance method 4.4.2 ďûě´ ŭ1Ͷɩ̕˧Ͷ̫Κȍ–΀_Njɽ̛ǻUþTn̛ superclass ɟ˓ >> s = String.new("foobar") => "foobar" >> s.class # ʙȌ s ȁƓ̫Ͷ => String >> s.class.superclass # ʙȌ String ̫˿Ͷ => Object >> s.class.superclass.superclass # Ruby 1.9 n̛ BasicObject k$ŃͶ => BasicObject >> s.class.superclass.superclass.superclass => nil їΚȍ–΀Šij 4.1 ȁ͈ǻUþT̺»String ̫˿Ͷɮ ObjectObject ̫˿Ͷɮ BasicObjectcɮ BasicObject Ɗˎɽ˿Ͷ5їʠ̫–΀žʿ Ruby žПѹɮѢ̛̫ üϬĴͶ̫Κȍ–΀LjŐб©ƏƊ _ò̓ Ruby ̫ʿͶɼΐѹɮΚȍο BasicObjectޘʄсˎɽ˿ͶїƊɮ“Ruby °̬žП”ȎʅƏ ҷ̫DZ) ij 4.1 String Ͷ̫Κȍ–΀ Ϭɹˤ‘̫̕ϵͶɼş̫ɟ˓ƊɮοƜÌȂΠ¢ǻUʌµƶ ĉ$ Word ̫ͶÓď ĉ$ palindrome? ɟ˓ŠʔÞЋҼЙěñЙɩѹ ʠ³ѕĬ true 125 >> class Word >> def palindrome?(string) >> string == string.reverse >> end >> end => nil ǻUþTȧ˽ҷ̫ɟƻn̛ >> w = Word.new => # >> w.palindrome?("foobar") => false >> w.palindrome?("level") => true # µƶ  Word žП Šʔlϳnjїoũɽ˸œӄƄ‚NjşǻU̴̫̫э»5Ų) ɞͶþɮüµƶ þTȷô Ūͨ "ìɕ̫ɟ˓ї(‚NjùǞɤ˼ÞЋɮŪͨ"Ͻ Word Κȍ String Ɗϡ5ŠR̀ 4.8 ȁ͈lϬѠ ¬ȸ¼ÿ˼ĊŸĴȸ¼ÿ ъ‘ї¢R̀їʠȃιȏ*À̫ Word Ų)˧Ҧȳ R̀ 4.8 Ĵȸ¼ÿ Ų) Word Ͷ >> class Word < String # Word Κȍο String >> # ŠʔŪͨ"ěοƜñтĊ̷ͪ³ѕĬ true >> def palindrome? >> self == self.reverse # self RϥїŪͨ"ʄс >> end >> end => nil ҷR̀ ̫ Word < String Ĵ Ruby ϥ͈Κȍ3.1 ω ͮÞKΑѐїʠҦ5´Ų)̫ palindrome? ɟ˓*ŏWord іȞɽȁɽŪͨ"Ȟɽ̫ɟ˓ >> s = Word.new("level") => "level" >> s.palindrome? => true >> s.length => 5 # µƶ ɞ̫ Word¶ţ~$ level # Word ųoþTĞư palindrome? ɟ˓ # Word ųoіΚȍ5Ūͨ"ȁɽ̫Ƥϰɟ˓ Word Κȍο StringǻUþTĴȸ¼ÿ ʙ̺Ͷ̫Κȍ–΀ >> s.class => Word >> s.class.superclass 126 => String >> s.class.superclass.superclass => Object Κȍ–΀Šij 4.2 ȁ͈ ͩ 4 ͥ Rails ηĊ̫ Ruby ij 4.2 R̀ 4.8 Ų)̫ Word ͶҵΦͶ̫Κȍ–΀ ĴR̀ 4.8 ˕DZϬʨʙÞЋěÞЋ̫ñтɮč̷ĈϬĴ Word Ͷ Ƽ̛їÞЋĴ Ruby ǻUn̛ self јϡƼ̛ Ĵ Word Ͷ self Rϥ̫ƊɮžПʄсȁTǻUþTn̛ self == self.reverse ʌʨʙÞЋɮčɮ Ĭɘ11 4.4.3 2Å=ġûď ϝ˼ΚȍɮNjǁœ̫ÉιѐĴĬɘ¸ɜ̫oũ Šʔιȏ palindrome? ʑ String ͶƊɹş5їʠ Ҧ5˜PžПŏǻUƊþTĴŪͨ"ŪҷҀЛ̛ palindrome? ɟ˓5̓ĴǻUіι̶ȷЛ̛ >> "level".palindrome? NoMethodError: undefined method `palindrome?\' for "level":String ɽ˸SGǨЃ̫ɮRuby ŠЄlї(‚Ruby ̫ͶþTϧȄƷјϡyɌŠЄˆǻUοƜїʠ̫ɱѫG˦Ê Aɟ˓ 12 >> class String >> # ŠʔŪͨ"ěοƜñтĊ̷ͪ³ѕĬ true 11. –: Ruby Ͷě self –ҎŪИҘЙ RailsTips ̫Class and Instance Variables in Ruby ɘ 12. 5ϵ JavaScript ̫Gþι̾ѱїÉιn̛Φ̫ͶêľžПȇŒͶ̫ɟƻͶbdzНЙέ Erik Eldridge Ȧ¬ї ˸ 127 >> def palindrome? >> self == self.reverse >> end >> end => nil >> "deified".palindrome? => true ǻ̾ѱĠ ɹ̃ Ruby ŠЄċΦ̫Ͷ ˦Êɟ˓Ǽ“deified͋Ôś$͋ɪ”ɮĬɘ þTyɌΦ̫ͶɮNjǁœ̫ÉιѐÉιǁœDZĘ̽ФX0œŠʔˎɽ Njş̫̜̕ċΦ̫Ͷ ˦ Êɟ˓ϧϻ$ɮş̫1ǭRails ο˼ɽNjş̫̜̕oŠĴ Web ư̛͘Ʈ ǻUΒƤϬѵõҀɮ̩͝ blank̫ˆ̛Ȁĉ*Ͷ̫ƊưВɮ͝ʣǼ̩͝ȁT Rails $ Ruby ˦Ê5  blank? ɟ˓ĭ$ Rails ȸ ¼ÿ_οÌÊц Rails ˦Ê̫ȇƒÉιǻUþT̺ ͈oĴ irb ƊþT >> "".blank? => true >> " ".empty? => false >> " ".blank? => true >> nil.blank? => true ǻUþT̺» Óď͝ʣ̫Ūͨ"ɮ̫͝emptyæɮ̩̫͝blankіϬ˕DZnil 0ɮ̩̫͝ ĭ$ nil ɮŪͨ"ȁTҷ̫R̀Зɪ5 Rails ˜ųɮȏ blank? ˦Ê» String ̫ŃͶ Object ̫ǻU _Ĵ 8.2.1 ω KΑ A Rails ȇƒ Ruby Ͷ̫oũ 4.4.4 ¼Ikď ϼЅͶěΚȍɩlþιϳnjbɺ̷ЉҌǻU*ÀKΑѐĴn̛ StaticPages ȸ¼ĩɩR̀ 3.16 class StaticPagesController < ApplicationController def home end def help end def about end end 128 ͩ 4 ͥ Rails ηĊ̫ Ruby l̓ĴþT̕ϵπƅɽ˸ι̕ϵїAR̫̀DZǜ5 StaticPagesController ɮ ͶΚȍο ApplicationControllerStaticPagesController Ͷ ɽɟ˓ homehelp ě aboutĭ$ Rails ȸ¼ÿ_Êцʄĵ̫ Rails ̒ŇȁTǻUþTĴȸ¼ÿ µƶ ȸ¼ĩʌʙ̺ Ů̫Κȍ–΀ 13 >> controller = StaticPagesController.new => # >> controller.class => StaticPagesController >> controller.class.superclass => ApplicationController >> controller.class.superclass.superclass => ActionController::Base >> controller.class.superclass.superclass.superclass => ActionController::Metal >> controller.class.superclass.superclass.superclass.superclass => AbstractController::Base >> controller.class.superclass.superclass.superclass.superclass.superclass => Object їΚȍ–΀Šij 4.3 ȁ͈ ǻUіþTĴȸ¼ÿ Л̛ȸ¼ĩ̫ÌkÌk˜ųƊɮɟ˓ >> controller.home => nil home Ìk̫ѕĬ~$ nilĭ$Ůɮ̫͝ ˕DZÌkˎɽѕĬ~ǼπƅˎѕĬ̻ʵҲϬ̫~ŠǻUĴͩ 3 ̺ͥ»̫home Ìk̴̫̫ɮ˪ʘΤҹή ɮѕĬ ~ѐǻЁnjˎɽĴXhĵɟЛ̛ѐ StaticPagesController.newїɮǚ(Ĭ8 êĭĴ:Rails ɮ̛ Ruby Π¢̫c Rails ɮ RubyɽA Rails ͶƊˆɱѫ̫ Ruby Ͷ ʠѐ0ɽA³nj̮ : Rails ̫ǁœÉιRails ɮÞ̫̌ ҒŭҕưВ׺: Ruby јϡŭ1ě̕ϵїƊɮ$H(Šʔl̫—ж ɮƷò Web ư̛͘ƮǻƶϿlŭ Rails Ÿŭ Ruby˼ĊŸĬ» Rails ̫êĭ 4.4.5 ö®ď ǻUѫѐµƶ Űɗ̫ͶʌΔʉž Ruby ̫KΑ  User ͶȼÀų̓ͩ 6 ̫ͥ User ʬľ »̴À$ʴǻUѹɮĴȸ¼ÿ Ų)Ͷ̫їʠNjǕȱc0ɽ˸̀̓ĴǻUϬĴư̛͘Ʈ̫ʢ̴DŽµƶ ĉ$ example_user.rb ̫ɘV¢‘R̀ 4.9 ̫Ź 13. lˎǐϬ̾ѱΚȍ–΀ ̫ʿͶǻ0̾ѱŮUѹɮƨH(̫ήǻM 2005 ƪƊƷţn̛ Ruby on Rails јϡƷò5 їþιDZĘ̽5Tҕӄ ̫ ͩ ǻɮƳʚͩ9lҲϬ̾ѱȁɽ̫Ĵ̾Љ0ιǺ$˾Ό̫ Rails Ʒò έǻUǃ˼ѹơʀɮͩ9˸ 129 ij 4.3 StaticPages ȸ¼ĩ̫Κȍ–΀ R̀ 4.9 User Ͷ̫R̀ example_user.rb class User attr_accessor :name, :email def initialize(attributes = {}) @name = attributes[:name] @email = attributes[:email] end def formatted_email "#{@name} <#{@email}>" end end ҷ̫R̀ɽNjŐϬЗɪ̫ǻU ʷʷʌ̺ҷїϡ attr_accessor :name, :email Ů$̛Ȁ̫ĉŪě Email ĵĸµƶ5ƓǝЇҕĩattribute accessors0ƊɮŲ)5“ϓógetter”ě“ІŲ setter”ɟ˓̛ʌóĬěЭ~ @name ě @email ųoõҀǻUĴ 2.2.2 ω KΑѐųoõҀĴ Rails ų 130 ͩ 4 ͥ Rails ηĊ̫ Ruby oõҀ̫DZ)Ĵ:ŮUοÌ̫Ĵϱij þ̛ήѫƤųoõҀ̫k̛ɮ̛ʌĴ Ruby Ͷ Ĉ̫ɟ˓*Җ`Ѩõ Ҁ~͙Ċ_ɹГΎ̫KΑї˸ųoõҀǟɮT @ ͨĂƷŘŠʔʂŲ)³˜~$ nil ͩ ɟ˓initializeĴ Ruby ɽ̆ʻDZ) ǃǻUȆϡ User.new ɩ_Л̛Вɟ˓ї initialize ɟ˓þTȷô ìɕattributes def initialize(attributes = {}) @name = attributes[:name] @email = attributes[:email] end attributes õҀ̫¶ţ~ɮ ̫͝ HashȁTǻUþTŲ) ˎɽĉŪǼˎɽ Email ĵĸ̛̫ȀĬǯ  4.3.3 ωŠʔҎūĴ³ѕĬ nilȁTŠʔˎŲ) :name Ҏ³ attributes[:name] _ѕĬ nil attributes[:email] 0ɮ ʠ ɼĊŲ)5 ĉ$ formatted_email ̫ɟ˓Ůn̛ϧЭ5~̫ @name ě @email õҀјϡȽ~΍Ǻ ʣƻφş̛̫Ȁ Email ĵĸ4.2.2 ω def formatted_email "#{@name} <#{@email}>" end ĭ$ @name ě @email ѹɮųoõҀŠ @ ͨĂȦɪȁTŮUĴ formatted_email ɟ˓ οÌþϮ ϽǻUȄƷȸ¼ÿÊцrequireїɘVųҠɈk ї̛ȀͶ >> require './example_user' # їƊɮÊцɘV̫ɟƻ => ["User"] >> example = User.new => # >> example.name # ѕĬ nilĭ$ attributes[:name] ɮ nil => nil >> example.name = "Example User" # Э~ ҵ nil ̫ĉŪ => "Example User" >> example.email = "user@example.com" # Э~ ҵ nil ̫ Email ĵĸ => "user@example.com" >> example.formatted_email => "Example User " ҷR̀ ̫˸Ă . Ĵ Unix ɮȦ“ǃÀ̴DŽ”./example_user ĔЊ Ruby ĴǃÀ̴DŽ ſȌїɘVȷ ʌ̫R̀µƶ5 ̛̫͝Ȁ˼Ċѫѐ̶ȷЭ~Ζ̷ư̫ƓǝʌȼpP̫ĉŪě Email ĵĸĭ$ɽ5R̀ 4.9 attr_accessor ѶϡȃιјϡЭ~ɈkǻUъ‘ example.name = "Example User" 131 Ruby _ƃ @name õҀ̫~І$ "Example User"email ƓǝͶb˼ĊþTĴ formatted_email n ̛ Š 4.3.4 ω KΑ̫ŠʔɼĊ ìɕɮ HashǻUƊþT̹̣ϊȠĂǻUþTȏ ӀŲ)ş̫ Hash `Ѩ Ζ initialize ɟ˓ʌµƶû ̛Ȁ >> user = User.new(name: "Michael Hartl", email: "mhartl@example.com") => # >> user.formatted_email => "Michael Hartl " Mͩ 7 ͥƷţǻU_n̛ Hash ¶ţÔžПї͑Ȏʅý‚“mass assignment”Ĵ Rails NjƤ̛ 4.5 ŒĘ ̓ĴΔʉž Ruby ДϷ̫KΑĴͩ 5 ͥǻU_şş̫¹̛їA̾ЉʌƷò͈o͘Ʈ ǻU_n̛ 4.4.5 ω µƶ̫ example_user.rb ɘVȁTǻƶϿȏŮ·Ҧ $ rm example_user.rb ˼Ċȏ˜P̫ɌÌȼB»R̀NƯ $ git add . $ git commit -m "Add a full_title helper" 4.6 Ė 1. ƃҷR̀ 4.10 ̫ҕĂȮǺćѢ̫ɟ˓Δćsplitshuffle ě join ų̓ ®ɕȏ ΖŲ Ūͨ" ̫ŪͨҼƮȄ4 2. TҷR̀ 4.11 $ϗʄƃ shuffle ɟ˓˦Ê» String Ͷ  3. µƶ Hash¯ºĉ$ person1person2 ě person3ƃĉ썞ư» :first ě :last Ҏ Ÿµƶ ĉ$ params ̫ Hashn params[:father] žư person1params[:mother] žư person2params[:child] žư person3ӎЈ  params[:father][:name] ̫~ɮčʵ͆ 4. Ȍ Ĵ΋̫ Ruby API ɘʦҘЙ Hash ̫ merge ɟ˓̫n̛ɟ˓ 5. ѥ‚к̽ Ruby Koans ŭ1 Ruby ‘Ғ̾Љ R̀ 4.10 Ȅ4Ūͨ"®ɕ̫Ӑʖ >> def string_shuffle(s) >> s.split('').?.? 132 >> end => nil >> string_shuffle("foobar") R̀ 4.11 ˦Ê» String Ͷ̫ shuffle ɟ˓Ӑʖ >> class String >> def shuffle >> self.split('').?.? >> end >> end => nil >> "foobar".shuffle ͩ 4 ͥ Rails ηĊ̫ Ruby 133 ĉ 5 ć …j– ͩ 4 ͥž Ruby ‚5ͮÞ̫KΑǻUЂϵ5ŠhĴư̛͘Ʈ Ƽ‘ʠƻϥѐƊˆĴ 4.3.4 ω Зѐ̫ї ʠƻϥ̓Ĵіɮ̫͝ʄͥǻU_‚AyɌȏ Bootstrap ʤʖƼ‘ư̛͘Ʈ ˼ĊŸ˦Ê AοŲ)̫ʠƻ1 ǻUі_ȏƝΒµƶ̫ҹҷoŠ“ӊҹ”ě“–:”ҹҷ˦Ê»ƞƎ 5.1 ωĴїѐ͘ ǻU_KΑƎѸ ϱijpartialRails м̜ě asset pipelineі_KΑ Sass5.2 ωǻUі_̛ɼɞ̫ RSpec Ȏʅѿʐͩ 3 ͥ ̫˜ЍɼĊǻUі_ċÀё¬NjѿϬ̫ ʷ ŠЄ̛ȀĴǻU̫Τͤ ˕ž ij 5.1 ͈o͘Ʈ“ӊҹ”̫ʐǜij 1. dzНЙέ Colm Tuite n̛ Bootstrap ѿ¢5ʄ2êʌ̫͈o͘Ʈ 134 ͩ 5 ͥ ŰĦƞƎ 5.1 éLĘ× ʄ2ɮ–: Web Ʒòήɮ Web ІϹ̫ѐĴ ̺гʌNjĽķ̫ư̛͘Ʈ Ʒò_ϽGȼгÏȁTʄ2 ǻUϬċƞƎ ˦Ê AΔʐŸÊ‘ A CSS ʐƶŃʄ̫ʠƻҦ5n̛οŲ)̫ CSS *ŏǻUі_n̛ Bootstrap̜ Twitter Ʒò̫Ʒˬ Web ІϹʤʖǻUіϬȧ˽ Ų̫ɟƻ΍ΏR̀ån̛ƎѸϱijʌwȥƞƎ ɘV̫Δʐ˧ɳѵœҀ̫R̀˥ʇĴƞƎɘV  Ʒò Web ư̛͘Ʈɩƌɨ̫ž̛Ȁ̠ҷɽΙͬůȵLjLj_žlɽȁƣÍĴʄ2Ċ˝Ź ǻ_ΒƤȽ‘Τ ҹ̫ʐǜijmockupĴ Web ӁŁΒƤ͖*$“΋ʤijwireframe”їɮžư̛͘Ʈɼΐɐʔ̫ϏijІ Ϲ2ʄͥœѸ¯ŹѹɮĴƷò 3.1 ω KΑ̫ҴǙҹҷҹҷ Óď Τͤ LOGOƀτʋŘѸěΤͤƱѸ їAΤҹ ɼѿϬ̫ ɮ“ӊҹ”Ů̫ʐǜijŠij 5.1 ȁ͈ij 5.7 ɮɼΐų̫̓ɐʔl_ò̓9έ*Җ̫ʗA ΎωɽȁĈoŠĴɼΐų̫̓ҹҷ ǻUʑ5  Rails LOGO——їˎH(–΀ĭ$ʐǜijˎǐϬ̟¬ ʿΎω ě*À ʠŠʔln̛ Git ‚̂ʄȸ¼̫Џ̓Ĵɼşµƶ ɞ¯Ɋ $ git checkout -b filling-in-layout 5.1.1 ĠƋī Ĵ͈o͘Ʈ ʑ҈ȷěʠƻ̫ͩ ʷϬyɌƞƎɘV application.html.erbʭn̛ɮĴR̀ 4.3 ˦Ê A HTML ΔʐǻUϬ˦Ê Aף A CSS classTîΤͤƀτƞƎɘV̫ŹìϮR̀ 5.1žĆѸ¯R̫̀Зɪ΃к˜ĊŠʔlќîNJ̫ǯ̺»ΔʔИʙ̺ij 5.2˕DZ ΔʔіɮNjϽ G˯DZ R̀ 5.1 ˦Ê AΔʐĊ̫ΤͤƞƎɘV app/views/layouts/application.html.erb <%= full_title(yield(:title)) %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %>
<%= yield %>
ǻUMLj̺ R̀ 5.1 ɞ˦Ê̫‹΁3.3.2 ωͮÞ̫KΑѐRails 4 әϻ_n̛ HTML5Š ȁ͈ĭ$ HTML5 ʜ¦іNjɞɽA˝ϲĩ̆ºɮчɧ̂ʄ̫ IE ˝ϲĩіˎɽےɊȥȁTǻ UÊц5 A JavaScript R͖̀k“HTML5 shim”ʌϵ¤їҕӄ Šɽ˸ùǞ̫ú˓ Ͷb̫ǻUþTȏŘѸ̫Ź͗‘ƎѸϱijŠR̀ 5.11 ȁ͈˼ĊŸʭЛ̛ render ȏїƎѸϱijȽ‘ƞƎ  R̀ 5.11 ΤͤŘѸ̫ƎѸϱij app/views/layouts/_header.html.erb ̓ĴǻUƝΒ̾ѱǚ(µƶƎѸϱij5ϽǻUʌʑěŘѸžư̫ΤͤƱѸĎlǼЄƝΒ̎»5ǻU_ȏї ƎѸϱijĚĉ$ _footer.html.erbɎĴƞƎ̴DŽ ìϮR̀ 5.127 R̀ 5.12 ΤͤƱѸ̫ƎѸϱij app/views/layouts/_footer.html.erb
Rails Tutorial by Michael Hartl
ěŘѸͶbĴƱѸǻUn̛ link_to µƶ»“–:”ҹҷě“γ΀”ҹҷ̫҈ȷĵĸɵɩn̛ádͨ #ě header ʠfooter ʜͭ0ɮ HTML5 ɞňÊ̫ ȧ˽ HTML shim ěŘѸƎѸϱijѼ̛̫ɟƻǻU0þTĴƞƎϱij ˪ʘƱѸƎѸϱijìϮR̀ 5.13 R̀ 5.13 Τ̫ͤƞƎÓďƱѸƎѸϱij app/views/layouts/application.html.erb <%= full_title(yield(:title)) %> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> <%= render 'layouts/shim' %> 7. lþιǯ̾ѱ$H(Ϭn̛ footer ʜͭě .footer class̜̕Ɗɮїʠ̫ʜͭž:GͶʌЗɹŹɫ̕ϵήѶ class ɮĭ$ Bootstrap ѾĴ̛ȁTnj̛ŠʔǴDZ̫Џ̛ div ʜͭRɻ footer 0ˎH(ҕӄ 148 ͩ 5 ͥ ŰĦƞƎ <%= render 'layouts/header' %>
<%= yield %> <%= render 'layouts/footer' %>
ǃ˼Šʔˎɽʠƻ̫ЏƱѸіɮNj̫ʠƻìϮR̀ 5.14˦ÊʠƻĊ̫ɐʔŠij 5.7 ȁ͈ R̀ 5.14 ˦ÊƱѸȁҲ̫ CSS app/assets/stylesheets/custom.css.scss . . . /* footer */ footer { margin-top: 45px; padding-top: 5px; border-top: 1px solid #eaeaea; color: #999; } footer a { color: #555; } footer a:hover { color: #222; } footer small { float: left; } footer ul { float: right; list-style: none; } footer ul li { 149 float: left; margin-left: 10px; } 5.2 Sass h asset pipeline Ĵчɞ̂ʄ̫ Rails ɼœ̫õÔɮňÊ5 asset pipelineїÉιþTɪɯȼӑŠ CSSJavaScriptěij́ͪҴǙ ЬˬɘVasset̫̚Ǻɐ̐ңeͰ̕ǺʄʄωǻU_ʫϲ  asset pipeline˼ĊŸKΑŠhn̛ Sass ї ̚Ǻ CSS Njǁœ̫Ƙ™Sass ̓Ĵɮ asset pipeline әϻ̫ Ѹ¯ 5.2.1 Asset pipeline Asset pipeline ž Rails‚5NjŐɌÌcž Rails ƷòέʌЗüɽ̆ǝҲϬ5ϵ Ьˬ̴DŽ˧ÞɘVmanifest fileіɽӀŌ̕ĩƼɉpreprocessor engine8ǻU_  ̫KΑ ij 5.7 ˦ÊƱѸĊ̫“ӊҹ”/static_pages/home 8. ʄωʖʐ̫qȰɮ Michael Erasmus ̫The Rails 3 Asset Pipeline in (about) 5 Minutes ɘɹ՝ŹИҘЙ Rails Ȧß ̫Asset Pipeline 150 ͩ 5 ͥ ŰĦƞƎ ʼnìü¥ Ĵ Rails 3.0 *ÀÓȠ 3.0ҴǙɘV¯ºɎĴŠ̫ public/ ̴DŽ • public/stylesheets • public/javascripts • public/images їAɘVř ̫ɘVѫѐИˇ http://example.com/stylesheets ͪĵĸ̶ȷòѡΖ˝ϲĩRails 3.0 *Ċ̫̂ʄ0þ Tї(‚ M Rails 3.1 Ʒţ»ɼɞ̫ Rails 4ҴǙɘVþTūɎĴʜ¦̴̫DŽ ĆɽĆ̛̫ѩ • app/assets ūɎǃÀư̛͘Ʈ̛»̫ЬˬɘV • lib/assets ūɎƷòĮҙοƜƷò̫R̀Ư̛»̫ЬˬɘV • vendor/assets ūɎͩɟR̀Ư̛»̫ЬˬɘV lþι̎»5ҷ̴̫DŽ ѹ_ɽ҂žĈЬˬͶľ̫ũ̴DŽoŠ $ ls app/assets/ images javascripts stylesheets ̓ĴǻUƊþT̾ѱ 5.1.2 ω custom.css.scss ūɎdΦ̛̫DZ ĭ$ custom.css.scss ɮư̛͘Ʈʄс ̛»̫ȁTȏŮūɎĴ app/assets/stylesheets  êRÉ( ǃlȏЬˬɘVūɎĴѢǃ̴̫DŽĊϬѫѐ˧ÞɘVĔЊ Railsǚ(ȏŮUćƫǺ ɘVn̛ Sprockets gemüѢ̛: CSS ě JavaScriptή_Ō̕ij́&oũϽǻU̺ ư̛͘Ʈәϻ̫ʠƻϥ˧ÞɘV ìϮR̀ 5.15 R̀ 5.15 ư̛͘Ʈ̫ʠƻϥ˧ÞɘV app/assets/stylesheets/application.css /* * This is a manifest file that'll automatically include all the stylesheets * available in this directory and any sub-directories. You're free to add * application-wide styles to this file and they'll appear at the top of the * compiled file, but it's generally better to create a new file per style * scope. *= require_self *= require_tree . */ їѾ̫–ҎR̀ɮ©ϡ CSS ˕ѽSprockets _ѫѐїA˕ѽÊц̷ư̫ɘV 151 /* *. *. *. *= require_self *= require_tree . */ ҷR̀ ̫ *= require_tree . _ȏ app/assets/stylesheets ̴DŽ ̫ȁɽ CSS ɘVѹƼ‘ư̛͘Ʈ̫ʠƻϥ  ҷїϡ *= require_self _ȏ application.css їɘV ̫ CSS 0Êцјʌ Rails ȼp̫әϻ˧ÞɘVþT˯зǻU̫ϬˇȁTʄ2_ž˜‚XhyɌRails Ȧß ɽ ͳҒKΑ asset pipeline ̫ɘͥВɘɽlҲϬ̾ѱ̫ɹ$ГΎ̫Ź Ŷxôk¢Ã ¦ōşЬˬɘVĊRails _n̛ AӀŌ̕ĩƼɉʌŌ̕ŮUѫѐ˧ÞɘVƃ˜ćƫ˼ĊòѡΖ˝ϲĩǻU ѫѐȇƒĉĔЊ Rails Ϭn̛ĠӀŌ̕ĩɼƤ̛̫ȇƒĉɮ Sass ɘV̫ .scssCoffeeScript ɘV̫ .coffeeERb ɘV̫ .erbǻUĴ 3.3.3 ωKΑѐ ERb5.2.2 ω_KΑ Sassʄɓ͘ҲϬn̛ CoffeeScript їɮ NjƄƚ̫ДϷþTΠЌǺ JavaScriptRailsCast –: CoffeeScript ̫ϱӃɮNjş̫‘Ғɓ͘ ӀŌ̕ĩƼɉþTћȷĴ гn̛ĭʶ foobar.js.coffee ü_n̛ CoffeeScript Ō̕ĩή foobar.js.erb.coffee _n̛ CoffeeScript ě ERb Ō̕ĩȧ˽ȇƒĉ̫ҼƮMāċƙŌ̕ȁT CoffeeScript Ō̕ĩ_Ȇϡ oõòvûÆñũŷ Asset pipeline Ƣʌ̫şŌ* ɮŮ_οÌ^ÔЬˬɘVĴ̚C̒Ň n̛ɐʔʏmCSS ě JavaScript ̫`Ι ΍ΏɟƻɮƃĈÉι̫R̀ɎĴĈ̫ɘV ήR̫̀ʣƻɮžGͶïş̫ɽNjŐ΢јϝ˼їžΠ͘ GĕNjïşcĴ̚C̒Ň n̛æɐ̐eÊцœҀ̫ɘV_ɪɯňÊҹҷÊцɩҖїɮdžĞ̛Ȁgӎɼ% 152 ͩ 5 ͥ ŰĦƞƎ Ϭ̫ĭ΁* n̛ asset pipeline̚C̒Ň ư̛͘Ʈȁɽ̫ʠƻѹ_ү »  CSS ɘV application.cssȁɽ JavaScript R̀ѹ_ү »  JavaScript ɘV javascript.jsήі_ é΢їAɘVÓȠ lib/assets ě vendor/assets ̷̫–ɘVȏǐϬ̫͝ʣ·Ҧ§ƄɘVœƄ їʠǻUƊɼş̫Ʃϣ5ɟҷ̫Ҳˇ Π͘Gĕn̛ʣƻïş̫ŐɘV̚C̒Ň n̛^ÔĊ̫ÞɘV 5.2.2 \ä£{ûÝ¡Į Sass ɮ ͑Π¢ CSS ̫ДϷMŐɟҷňǁ5 CSS ̫ÉιʄωǻU_KΑɼ%Ϭ̫ÉιƖŝěõҀ іɽ ɮ mixin_Ĵ 7.1.1 ω KΑ Š 5.1.2 ω ̫ͮÞKΑSass Ɋȥ ͑ĉ$ SCSS ̫ʣƻȇƒĉ$ .scssїɮ CSS ú˓̫ ȇƒү SCSS üɮ$ CSS ˦Ê5 AÉιήˎɽŲ)’ɞ̫ú˓90ƊɮЗȁɽć˓̫ CSS ɘVѹɮć˓̫ SCSS ɘ VїžƝΒŲ)5ʠƻ̫һ̴ʌЗɮVş8ĴǻU̫͘Ʈ ĭ$Ϭn̛ BootstrapM ƷţƊn̛5 SCSSRails ̫ asset pipeline _οÌn̛ Sass ӀŌ̕ĩŌ̕ȇƒĉ$ .scss ̫ɘVȁT custom.css.scss ɘ V_ӊΒ̜ Sass ӀŌ̕ĩŌ̕˼ĊƼ‘͘Ʈ̫ʠƻϥ ŸòѡΖ˝ϲĩ ‘~ ʠƻϥ ΒƤ_Ų)Ɩŝ‹΁̫ʠƻoŠĴR̀ 5.6 Ų)5 .center ě .centr h1 ʠƻ .center { text-align: center; } .center h1 { margin-bottom: 10px; } n̛ Sass þƃ˜Ɍ¢Ǻ .center { text-align: center; h1 { margin-bottom: 10px; } } ҷR̀ ̫ h1 _οÌƖ‘ .center  Ɩŝіɽû ͑Džƻú˓͙ɽĈĴR̀ 5.8 ɽŠ̫R̀ 9. Sass L˼Ɋȥчɨ̫ .sass ʣƻїʣƻ̷žʌЗɹͮ˖ϊȠĂɹƅcɮž̓ūһ̴ŕïşƝΒ˾ǣ CSS ̫Gŭ 1ҭƴ0̷žɹœ 153 #logo { float: left; margin-right: 10px; font-size: 1.7em; color: #fff; text-transform: uppercase; letter-spacing: -1px; padding-top: 9px; font-weight: bold; line-height: 1; } #logo:hover { color: #fff; text-decoration: none; } ˜ LOGO ̫ id #logo ¬̓5ʭ ʭɮÞ̌¬̫̓û ʭɮě hover aͶ г¬̫̓ӛʜǥƒ˜ɩ̫ ʠƻŠʔϬƖŝͩ9ʠƻǻUҲϬƼ̛˿Έ‹΁ #logoĴ SCSS n̛ & ͨĂų̓ #logo { float: left; margin-right: 10px; font-size: 1.7em; color: #fff; text-transform: uppercase; letter-spacing: -1px; padding-top: 9px; font-weight: bold; line-height: 1; &:hover { color: #fff; text-decoration: none; } } ȏ SCSS тȮǺ CSS ɩSass _ȏ &:hover ΠЌǺ #logo:hover ї͑ƖŝɟƻѹþT̛:R̀ 5.14 ̫ƱѸʠƻтȮĊ̫ʠƻŠ footer { margin-top: 45px; padding-top: 5px; border-top: 1px solid #eaeaea; color: #999; 154 ͩ 5 ͥ ŰĦƞƎ a{ color: #555; &:hover { color: #222; } } small { float: left; } ul { float: right; list-style: none; li { float: left; margin-left: 10px; } } } οƜÌȂтȮ R̀ 5.14 ɮҌ̫Ό1тȮ*ĊlưВӎЈ  CSS ɮčіιʵƤn̛ [ţ Sass ŠЄǻUοŲ)õҀʌѵѿŎїʠ0þT¢¬ɹ™ϥ̓Ç̫R̀oŠR̀ 5.7 ěR̀ 5.14 ѹѿŎn ̛5Ĉ ӅχR̀ h2 { . . . color: #999; } . . . footer { . . . color: #999; } ҷR̀ ̫ #999 ɮˣ˵χligh grayǻUþT$ŮŲ) õҀ 155 $lightGray: #999; ˼ĊǻUƊþTїʠ¢ SCSS $lightGray: #999; . . . h2 { . . . color: $lightGray; } . . . footer { . . . color: $lightGray; } ĭ$ˆ $lightGray їʠ̫õҀĉˀ #999 ɹ™ЗɪǝȁT$ˎɽѿŎn̛̫~Ų)õҀLjLj0ɮNjɽ̛̫ Bootstrap ʤʖŲ)5NjŐӅχõҀBootstrap ҹҷ ɽїAõҀ̫ LESS Džƻїҹҷ ̫õҀn̛̫ɮ LESS ú˓ήɮ Sass ú˓ѐ bootstrap-sass gem $ǻUȼp5žư̫ Sass Džƻ9έ*Җ̫žư–΀0ҭ̎ ¬LESS n̛ @ ͨĂŲ)õҀή Sass n̛ $ ͨĂĴ Bootstrap ̫õҀҹҷǻUþT̺»$ˣ˵χŲ)̫õҀ @grayLight: #999; 0ƊɮЗĴ bootstrap-sass gem _ɽ žư̫ SCSS õҀ $grayLightǻUþT̛ŮȮȳοƜŲ)̫ $lightGray õҀ h2 { . . . color: $grayLight; } . . . footer { 156 ͩ 5 ͥ ŰĦƞƎ . . . color: $grayLight; } n̛ Sass ȼp̫ƖŝěõҀÉιĊnj»̫Űɗ SCSS ɘVŠR̀ 5.16 ȁ͈їʼR̀ n̛5 Sass Džƻ̫Ӆχõ Ҁì˽ Bootstrap õҀҹҷ Ų)̫ LESS Džƻ̫ӅχõҀěΦ̫Ӆχĉ͖oŠwhite Rϥ #fff10 Йº˕DZ  footer ʜͭʠƻɪɯ̫Ɍј R̀ 5.16 n̛ƖŝěõҀтȮĊ̫ SCSS ɘV app/assets/stylesheets/custom.css.scss @import "bootstrap"; /* mixins, variables, etc. */ $grayMediumLight: #eaeaea; /* universal */ html { overflow-y: scroll; } body { padding-top: 60px; } section { overflow: auto; } textarea { resize: vertical; } .center { text-align: center; h1 { margin-bottom: 10px; } } 10. Ќέ˕ υƶϿĴ CSS n̛Ӆχĉ͖ĭ$Ĉ̫˝ϲĩěĈ̫΀ΙžĈ Ӆχ̫˪ʘɽȁĈˎɽn̛ٔ ј¼̫ӅχR̀¦͆ 157 /* typography */ h1, h2, h3, h4, h5, h6 { line-height: 1; } h1 { font-size: 3em; letter-spacing: -2px; margin-bottom: 30px; text-align: center; } h2 { font-size: 1.2em; letter-spacing: -1px; margin-bottom: 30px; text-align: center; font-weight: normal; color: $grayLight; } p{ font-size: 1.1em; line-height: 1.7em; } /* header */ #logo { float: left; margin-right: 10px; font-size: 1.7em; color: white; text-transform: uppercase; letter-spacing: -1px; padding-top: 9px; font-weight: bold; line-height: 1; &:hover { color: white; text-decoration: none; } } 158 ͩ 5 ͥ ŰĦƞƎ /* footer */ footer { margin-top: 45px; padding-top: 5px; border-top: 1px solid $grayMediumLight; color: $grayLight; a{ color: $gray; &:hover { color: $grayDarker; } } small { float: left; } ul { float: right; list-style: none; li { float: left; margin-left: 10px; } } } Sass ȼp5NjŐÉιþT̛ʌͮÔʠƻϥѐR̀ 5.16 ư̈»5ɼ%Ϭ̫Éιїɮş̫ƷͦɹŐÉιИ ʙ̺ Sass Τͤ 5.3 –ûť» ǻUƝΒ$Τ̫ͤƞƎŲ)5̺гʌіҌ̫ʠƻҷϬȏ҈ȷ ɵɩn̛̫ádͨ # ȮǺ̻ʵ̫҈ȷĵĸǃ ˼ǻUþTˆҷїʠȂÌʑ҈ȷ About ѐїʠŕͨć Rails ӈʣ έ“–:”ҹҷ̫ĵĸŠʔɮ /about ήɮ /static_pages/about Ɗş5 Ÿέ Rails 1ǭn̛™ĉм̜named routeʌȦŲ҈ȷĵĸ̷ư̫R̀Š <%= link_to "About", about_path %> n̛ї͑ɟƻιɹş̫ϥэ҈ȷ URI ěм̜̫žư–΀Šϥʣ 5.1 ȁ͈ʄͥŰΔ*ÀҦ5ɼĊ ҈ȷ* ŏ˜P̫҈ȷѹ_ІŲşͩ 8 ͥ_˦ÊɼĊ  159 ϥʣ 5.1 Τͤ ҈ȷ̫м̜ě URL ĵĸ̫ɭƂ–΀ ҹҷ URL žư̫м̜ “ӊҹ” / root_path “–:” /about about_path “ƣÍ” /help help_path “γ΀” /contact contact_path “˕ž” /signup signup_path “̨DŽ” /signin signin_path ΚΛ*ÀϽǻU˦Ê “γ΀”ҹҷͩ 3 ̫ͥ Ό1ӄ˜ЍŠR̀ 5.17 ȁ͈DžƻěR̀ 3.19 ƛ Ő R̀ 5.17 “γ΀”ҹҷ̫˜Ѝ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do . . . describe "Contact page" do it "should have the content 'Contact'" do visit '/static_pages/contact' expect(page).to have_content('Contact') end it "should have the title 'Contact'" do visit '/static_pages/contact' expect(page).to have_title("Ruby on Rails Tutorial Sample App | Contact") end end end lưВ̺ ї˜ЍɮčɮŗХ̫ $ bundle exec rspec spec/requests/static_pages_spec.rb їѾϬѼ̛̫ʷӏě 3.2.2 ω ˦Ê“–:”ҹҷ̫ʷӏɮ ρ̫ ɹɞм̜ІΦìϮR̀ 5.18˼ĊĴ StaticPages ȸ¼ĩ ˦Ê contact ÌkìϮR̀ 5.19ɼĊŸΠ¢“γ΀”ҹҷ̫ϱijìϮR̀ 5.20 160 R̀ 5.18 ˦Ê“γ΀”ҹҷ̫м̜ІΦ config/routes.rb SampleApp::Application.routes.draw do get "static_pages/home" get "static_pages/help" get "static_pages/about" get "static_pages/contact" . . . end R̀ 5.19 ˦Ê“γ΀”ҹҷžư̫Ìk app/controllers/static_pages_controller.rb class StaticPagesController < ApplicationController . . . def contact end end R̀ 5.20 “γ΀”ҹҷ̫ϱij app/views/static_pages/contact.html.erb <% provide(:title, 'Contact') %>

Contact

Contact Ruby on Rails Tutorial about the sample app at the contact page.

Ÿ̺ ˜ЍɮčþTѫѐ $ bundle exec rspec spec/requests/static_pages_spec.rb ͩ 5 ͥ ŰĦƞƎ 5.3.1 ŋ÷æŀ ҴǙҹҷ̫үǺ˜ЍΠ¢Ű*ĊŸΠ¢м̜˜ЍƊͮÞ5 üҲȏͅΠ̫̀ĵĸȮǺϥʣ 5.1 ̷ư̫™ĉм̜ ƊþT50ƊɮЗϬȏ visit '/static_pages/about' yɌ$ visit about_path 161 ˜P̫ҹҷ0їʠ‚yɌĊ̫ΔʔŠR̀ 5.21 ȁ͈ R̀ 5.21 ™ĉм̜˜Ѝ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do describe "Home page" do it "should have the h1 'Sample App'" do visit root_path expect(page).to have_content('Sample App') end it "should have the base title" do visit root_path expect(page).to have_title("Ruby on Rails Tutorial Sample App") end it "should not have a custom page title" do visit root_path expect(page).not_to have_title('| Home') end end describe "Help page" do it "should have the h1 'Help'" do visit help_path expect(page).to have_content('Help') end it "should have the title 'Help'" do visit help_path expect(page).to have_title("Ruby on Rails Tutorial Sample App | Help") end end describe "About page" do it "should have the h1 'About Us'" do visit about_path expect(page).to have_content('About Us') end 162 ͩ 5 ͥ ŰĦƞƎ it "should have the title 'About Us'" do visit about_path expect(page).to have_title("Ruby on Rails Tutorial Sample App | About Us") end end describe "Contact page" do it "should have the content 'Contact'" do visit contact_path expect(page).to have_content('Contact') end it "should have the title 'Contact'" do visit contact_path expect(page).to have_title("Ruby on Rails Tutorial Sample App | Contact") end end end ěLjƤ ʠ̓ĴưВ̺ ˜ЍɮčɮŗХ̫Άχ $ bundle exec rspec spec/requests/static_pages_spec.rb ҼtЗ NjŐGѹ_ϳnjR̀ 5.21 ɽNjŐѿŎ0NjĥĨǻU_Ĵ 5.3.4 ωјϡѿʐ 5.3.2 Rails ŋ÷ ǻUƝΒΠ¢5҂žȁɽ URL ĵĸ̫˜Ѝ̓ĴƊϬų̓їAĵĸ5Š 3.1 ωȁЗRails n̛ config/ routes.rb ɘVІΦ URL ĵĸ̫ɭƂ–΀Šʔl̺ әϻ̫м̜ɘV_ò̓ŹNjʇ4ѐіɮιȼp AƣÍ̫ĭ$ɽNjŐ˕ѽЗɪ5Ćм̜̫ɭƂ–΀ǻƶϿlȌɩҖѫЙ м̜ɘV0ƶϿlҘЙ  Rails Ȧß Гϵ Rails м̜ ɘɹˤ‘̫5ϵ м̜ Ų)™ĉм̜Ϭȏ get 'static_pages/help' yɌ$ match '/help', to: 'static_pages#help', via: 'get' їʠĴ /help ĵĸƊɽ5 þЇҕ̫ҹҷĞư GET Иˇ0Ų)5 ĉ$ help_path ̫™ĉм̜ В®ɕ_ѕĬ̷ưҹҷ̫ĵĸ˜ųȏ match ȮǺ get ɐʔɮ ʠ̫ѐn̛ match ɹͨć·Ų ˜Pҹҷ0Ϭ‚ͶbyɌΔʔŠR̀ 5.22 ȁ͈ѐ“ӊҹ”ɽ˸̆ʻìϮR̀ 5.24 163 R̀ 5.22 ҴǙҹҷ̫м̜ config/routes.rb SampleApp::Application.routes.draw do match '/help', to: 'static_pages#help', via: 'get' match '/about', to: 'static_pages#about', via: 'get' match '/contact', to: 'static_pages#contact', via: 'get' . . . end Šʔϻ̻ҘЙR̀ 5.22ǼЄ_ò̓Ů̫k̛oŠl_ò̓ match '/about', to: 'static_pages#about', via: 'get' _ÖѺ» /about ĵĸ̫ GET Иˇƫƃ˜¯ò» StaticPages ȸ¼ĩ̫ about Ìk*À̫ІΦDZijɹɪɯ ǻƯ get 'static_pages/about' 0þTnj»̷Ĉ̫ҹҷѐ /about ̫ĵĸDžƻɹͮ˖ήŠÀҷȼ»̫match '/about' _ο̵ƶ™ ĉм̜®ɕþTĴȸ¼ĩěϱij n̛ about_path -> '/about' about_url -> 'http://localhost:3000/about' ˕DZabout_url ѕĬ̫ΔʔɮŰɗ̫ URL ĵĸ http://localhost:3000/aboutѸΧĊ_̛ųҠ̫ŁĉɻȮ localhost:3000oŠ example.comŠ 5.3 ω̛̫˓ŠʔüǯѕĬ /aboutn̛ about_path ƊþT 5ʄ2Ńʄѹ_n̛ǭ̛̫ path DžƻѐĴҹҷтċɩ_n̛ url Džƻĭ$ HTTP ʜ¦ϬˇтċĊ̫ĵ ĸ$Űɗ̫ URLѐœŐɕ˝ϲĩѹþTʵƤn̛ї͑Džƻ ІΦ5їAм̜*Ċ“ƣÍ”ҹҷ“–:”ҹҷě“γ΀”ҹҷ̫˜ЍưВƊþTѫѐ5 $ bundle exec rspec spec/requests/static_pages_spec.rb ѐ“ӊҹ”̫˜ЍіɮŗХ̫ ϬІΦ“ӊҹ”̫м̜þTn̛Š̫R̀ match '/', to: 'static_pages#home', via: 'get' ѐˎǐϬї(‚Rails Ĵм̜ІΦɘV̫Ѹ$ʢĵĸ /ɚ΋ȼp5̆º̫ІΦɟƻìϮR̀ 5.23 R̀ 5.23 ˕ѽȳ̫ʢм̜ІΦЗɪ config/routes.rb 164 ͩ 5 ͥ ŰĦƞƎ SampleApp::Application.routes.draw do . . . # You can have the root of your site routed with "root" # just remember to delete public/index.html. # root :to => "welcome#index" . . . end ȧ˽ѝЗɪǻUȏʢĵĸ / ɭƂ»“ӊҹ”ìϮR̀ 5.24 R̀ 5.24 ˦Êʢĵĸ̫м̜ІΦ config/routes.rb SampleApp::Application.routes.draw do root to: 'static_pages#home' match '/help', to: 'static_pages#help', via: 'get' match '/about', to: 'static_pages#about', via: 'get' match '/contact', to: 'static_pages#contact', via: 'get' . . . end ҷ̫R̀_ȏʢĵĸ / ɭƂ» /static_pages/home ҹҷ0ƊɮЗ http://localhost:3000/ ̫Źěij 3.1 ̫ Rails әϻҹҷ ʠ5Ĉɩі̚Ǻ5 URL ĵĸƣÍɟ˓Šȁ͈ root_path -> '/' root_url -> 'http://localhost:3000/' πʶȁɽҴǙҹҷ̫м̜ѹІΦş5ήȁɽ˜ЍưВѹþTѫѐ5 $ bundle exec rspec spec/requests/static_pages_spec.rb ҷǻUϬĴƞƎ Ƚ‘їA҈ȷ 5.3.3 165 Ɍ$ <%= link_to "About", about_path %> ˜P҈ȷTʶͶȹ MŘѸƎѸϱij _header.html.erb Ʒţїϱij Óď5»“ӊҹ”ě“ƣÍ”ҹҷ̫҈ȷɤ˼ϬžŘѸϱ ij‚yɌҼtƊȧ˽Τҹ̫ǭo$ LOGO ˦Ê »“ӊҹ”̫҈ȷĎìϮR̀ 5.25 R̀ 5.25 ŘѸƎѸϱijÓď A҈ȷ app/views/layouts/_header.html.erb ͩ 8 ͥȃ_$“˕ž”ҹҷІΦ™ĉм̜ȁT̓Ĵіɮ̛ádͨ # RɻВҹҷ̫ĵĸ іɽ Óď҈ȷ̫ɘVɮƱѸƎѸϱij _footer.html.erbɽ»“–:”ҹҷě“γ΀”ҹҷ̫҈ȷìϮR̀ 5.26 R̀ 5.26 ƱѸƎѸϱijÓď A҈ȷ app/views/layouts/_footer.html.erb
Rails Tutorial by Michael Hartl
166 ͩ 5 ͥ ŰĦƞƎ Šʶ ʌͩ 3 ͥµƶ̫ȁɽҴǙҹҷ̫҈ȷѹʑƞƎ5T“–:”ҹҷ$oъ‘ /aboutƊ_ј‘Τ̫ͤ“– :”ҹҷŠij 5.8 ҼtЗ Ϭ˕DZϝ˼ǻUˎɽΠ¢˜Ѝʨ˜ƞƎ ɮčÓďїA҈ȷѐŠʔˎɽІΦм̜̫ЏÀҷ̫ ˜Ѝ0_ŗХxlþTȏR̀ 5.22 ̫м̜˕ѽȳŸѓϡ˜ЍʌӎЈ ʨʙ҈ȷɮčȦċʵ͆ҹҷ̫˜Ѝ R̀ìϮ 5.6 ω ij 5.8 “–:”ҹҷ /about 5.3.4 ČO RSpec æŀ$ÿ Ĵ 5.3.1 ω ЗѐҴǙҹҷ̫˜Ѝɽ˸ĥĨ0ɽAѿŎìϮR̀ 5.21ʄωǻUƊ_n̛ Aɼɞ̫ RSpec ̆ǝȏ˜Ѝõnjͮ˖ A^Ү A ̺ ŠhɌјҷ̫R̀ describe "Home page" do it "should have the content 'Sample App'" do visit root_path expect(page).to have_content('Sample App') end 167 it "should have the base title" do visit root_path expect(page).to have_title("Ruby on Rails Tutorial Sample App") end it "should not have a custom page title" do visit root_path expect(page).not_to have_title('| Home') end end ǻU˕DZ»˜Ѝ̛oѹЇҕ5ʢĵĸn̛ before ĻþT˟ҦїѿŎ describe "Home page" do before { visit root_path } it "should have the content 'Sample App'" do expect(page).to have_content('Sample App') end it "should have the base title" do expect(page).to have_title("Ruby on Rails Tutorial Sample App") end it "should not have a custom page title" do expect(page).not_to have_title('| Home') end end ҷ̫R̀n̛ before { visit root_path } Ĵʿ˜Ѝ̛oѓϡ*ÀЇҕʢĵĸbefore ɟ˓іþTn̛ºĉ before(:each) Л̛ іɽR̀Ĵʿ̛o ѹ¬̓5ǻUn̛5 it "should have the content 'Sample App'" do Ĉɩіn̛5 expect(page).to have_content('Sample App') 168 ͩ 5 ͥ ŰĦƞƎ 9έϝ˼DžƻĈϬϥэ̫DZǜæɮ̷Ĉ̫ή̛oѹƼ̛5 page õҀǻUþTĔЊ RSpecpage Ɗ ɮϬ˜Ѝ̫žПsubjectїʠƊþTѵŐʭn̛ page subject { page } ˼ĊŸn̛ it ɟ˓̫û ͑Džƻȏ˜ЍR̀ěȻѝɘʄć9$ it { should have_content('Sample App') } ĭ$Ȧɪ5 subject { page }ȁTЛ̛ should ɩƊ_οÌn̛ Capybara ȼp̫ page õҀìϮ 3.2.1 ω n̛їAȎƚþTȏ“ӊҹ”̫˜Ѝõnjͮ˖ A subject { page } describe "Home page" do before { visit root_path } it { should have_content('Sample App') } it { should have_title("Ruby on Rails Tutorial Sample App") } it { should_not have_title('| Home') } end їʠR̺̀гʌƊσɿŐ5ѐʜӄ̫˜Ѝіɽ˸ґ˜ųR̀ 5.21 œŐɕʜӄѹɮїʠ̫ґʜӄ "Ruby on Rails Tutorial Sample App | About" 3.5 ω̫Ό1ӄƶϿŲ)  base_title õҀŸn̛Ūͨ"Ƚ~ʌ˟ҦїѿŎìϮR̀ 3.31ǻUþT ɹј ʷŲ) ěR̀ 4.2 full_title Ͷb̫ɟ˓ $ʶǻUϬɞƶ spec/support ɘVř˼ĊĴ˜ ɞƶ RSpec ѫ̛®ɕɘV utilities.rbìϮR̀ 5.27 R̀ 5.27 RSpec ѫ̛®ɕɘVÓď full_title ɟ˓ spec/support/utilities.rb def full_title(page_title) base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? base_title else "#{base_title} | #{page_title}" end end 169 ˜ųїƊɮR̀ 4.2 ѶƣÍɟ˓̫Ŏ¼ѐŲ)̫̌͢ɟ˓þTȬϓʜӄ“•Ѹ¯ ̫ҌЕ˜ųї ʠ0ŕҶnjfɹş̫0ɹǁœ̫ɟ˓ɮ̶ȷ˜ЍêʌѶ full_title ƣÍɟ˓ìϮ 5.6 ω ̫Ό1 RSpec _οÌÊц spec/support ̴DŽ ̫ɘVȁTǻUƊþTȧ˽Š̫ɟƻΠ¢“ӊҹ”̫˜Ѝ subject { page } describe "Home page" do before { visit root_path } it { should have_content('Sample App') } it { should have_title(full_title('')) } end ҷǻUϬ̛Ͷb“ӊҹ”̫ɟ˓ʌͮÔ“ƣÍ”ҹҷ“–:”ҹҷě“γ΀”ҹҷ̫˜ЍΔʔŠR̀ 5.28 ȁ͈ R̀ 5.28 ͮÔĊ̫ҴǙҹҷ˜Ѝ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do subject { page } describe "Home page" do before { visit root_path } it { should have_content('Sample App') } it { should have_title(full_title('')) } it { should_not have_title('| Home') } end describe "Help page" do before { visit help_path } it { should have_content('Help') } it { should have_title(full_title('Help')) } end describe "About page" do before { visit about_path } it { should have_content('About') } it { should have_title(full_title('About Us')) } end 170 ͩ 5 ͥ ŰĦƞƎ describe "Contact page" do before { visit contact_path } it { should have_content('Contact') } it { should have_title(full_title('Contact')) } end end ̓ĴưВӎЈ ˜ЍR̀ɮčіþTѫѐ $ bundle exec rspec spec/requests/static_pages_spec.rb R̀ 5.28 ̫ RSpec ˜ЍˀR̀ 5.21 ͮÔŐ5˜ųіþTõnjɹͮ˖ГϮ 5.6 ωĴ͈o͘Ʈȷʌ̫Ʒò ѐ͘ üϬþTǻUѹ_n̛ї͑ͮ˖̫ɟƻ 5.4 ö®å>ĉã $5ŰΔʄ̴̫ͥʜʄωǻUϬІΦ“˕ž”ҹҷ̫м̜$ʶϬµƶͩ9ȸ¼ĩїɮŠЄ̛Ȁ˕žɼѿϬ̫ ʷ̛Ȁʬľ_Ĵͩ 6 ͥʐƶɗ˕žÉι³_Ĵͩ 7 ͥŰǺ 5.4.1 Users ¼Ik µƶͩ ȸ¼ĩ StaticPages ɮNj'TÀ̫85іɮĴ 3.1 ω ̓ĴǻUϬµƶͩ95Users ȸ¼ĩě* À ʠǻUn̛ generate ĚSµƶȁҲ̫ȸ¼ĩӐʖÓď̛Ȁ˕žҹҷȁҲ̫ÌkѴ˽ Rails ̫ REST ʖ ʐ·ŲǻUȏїÌkĚĉ$ newƃ˜`ѨΖ generate controller ƊþTο̵ƶїÌk5ìϮR ̀ 5.29 R̀ 5.29 ̚Ǻ Users ȸ¼ĩÓď new Ìk $ rails generate controller Users new --no-test-framework create app/controllers/users_controller.rb route get "users/new" invoke erb create app/views/users create app/views/users/new.html.erb invoke helper create app/helpers/users_helper.rb invoke assets invoke coffee create app/assets/javascripts/users.js.coffee invoke scss create app/assets/stylesheets/users.css.scss 171 їĚS_µƶ Users ȸ¼ĩіɽ˜ ̫ new ÌkìϮR̀ 5.30ě ád̛̫ϱijɘVìϮR̀ 5.31 R̀ 5.30 әϻ̚Ǻ̫ Users ȸ¼ĩÓď new Ìk app/controllers/users_controller.rb class UsersController < ApplicationController def new end end R̀ 5.31 әϻ̚Ǻ̫ new Ìkϱij app/views/users/new.html.erb

Users#new

Find me in app/views/users/new.html.erb

5.4.2 “å>”Ųűû URL pq 5.4.1 ω ̚Ǻ̫R̀_Ĵ /users/new ĵĸžư ҹҷѐŠϥʣ 5.1ȁ͈ǻUơʀ“˕ž”ҹҷ̫ĵĸɮ /signup$ʶě 5.3 ω ʠӊϬΠ¢үǺ˜ЍþTѫѐҷ̫ĚS̚Ǻ $ rails generate integration_test user_pages ˼Ċȧ˽R̀ 5.28 ҴǙҹҷ˜ЍR̫̀DžƻǻUϬΠ¢˜Ѝʨ˜“˕ž”ҹҷ ɮčɽ h1 ě title ʜͭŠ R̀ 5.32 ȁ͈ R̀ 5.32 Users ȸ¼ĩ̫˜ЍR̀Óď“˕ž”ҹҷ̫˜Ѝ̛o spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do subject { page } describe "signup page" do before { visit signup_path } it { should have_content('Sign up') } it { should have_title(full_title('Sign up')) } end end ě*À ʠþTȆϡ rspec ĚSѓϡ˜Ѝ $ bundle exec rspec spec/requests/user_pages_spec.rb 172 ͩ 5 ͥ ŰĦƞƎ ѐɽ ˸Ϭ˕DZlіþTȦŲɗ̴DŽʌѓϡȁɽ̫ request ˜Ѝ $ bundle exec rspec spec/requests/ Ĉ̕lþιіǯ̾ѱǚ(ѓϡ’Ѹ˜Ѝ $ bundle exec rspec spec/ $5˜Ѝ’ҷĴʄ2Ċ˝Ź ǻU υѹ_n̛їĚSѓϡȁɽ̫˜ЍҼtЗ lϬ̾ѱl0þ Tn̛ Rake ̫ spec XËѓϡ˜ЍlþιϮѐ˜PGїʠn̛ $ bundle exec rake spec 8ųlþTüъ‘ rakeĭ$ rake ̫әϻXËƊɮѓϡ˜Ѝ̓Ĵġ ̫ҕӄɮѓϡ˜Ѝ_ȔҌ ĭ$іˎɽ¦ōş“˜ЍɕȰƯ”ǻU_Ĵ 6.2.1 ω ГΎKΑ ǻUƝΒ$ Users ȸ¼ĩ̚Ǻ5 new ÌkŠϬ˜ЍѫѐҲϬʵ͆ІΦм̜іϬɽ̷ưŹ̫ϱijɘVǻU ȧ˽R̀ 5.22 ̫ɟƻ$“˕ž”ҹҷʑ match '/signup' м̜ІΦìϮR̀ 5.33 R̀ 5.33 “˕ž”ҹҷ̫м̜ІΦ config/routes.rb SampleApp::Application.routes.draw do get "users/new" root to: 'static_pages#home' match '/signup', to: 'users#new', via: 'get' match '/help', to: 'static_pages#help', via: 'get' match '/about', to: 'static_pages#about', via: 'get' match '/contact', to: 'static_pages#contact', via: 'get' . . . end ˕DZǻUw̢5 get "users/new" ІΦїɮȸ¼ĩ̚ǺĚSR̀ 5.29οÌ˦Ê̫м̜ŠϬм̜þ ̛їІΦіι·Ҧѐїͨć REST ·ŲìϮϥʣ 2.2_Ĵ 7.1.2 ω·Ҧ ϬϽ˜Ѝѫѐϱij іϬɽ̷ư̫ h1 ě titleìϮR̀ 5.34 R̀ 5.34 “˕ž”ҹҷϱij app/views/users/new.html.erb <% provide(:title, 'Sign up') %>

Sign up

Find me in app/views/users/new.html.erb

173 ̓ĴR̀ 5.32 “˕ž”ҹҷ̫˜ЍưВþTѫѐ5ҷϬ‚̫Ɗɮ$“ӊҹ” ̫˕žȧ҄Ê҈ȷě˜P̫ ™ĉм̜ ʠmatch '/signup' _̚Ǻ signup_path ɟ˓̛ʌ҈ȷ»“˕ž”ҹҷìϮR̀ 5.35 R̀ 5.35 ȏȧ҄҈ȷ»“˕ž”ҹҷ app/views/static_pages/home.html.erb

Welcome to the Sample App

This is the home page for the Ruby on Rails Tutorial sample application.

<%= link_to "Sign up now!", signup_path, class: "btn btn-large btn-primary" %>
<%= link_to image_tag("rails.png", alt: "Rails"), 'http://rubyonrails.org/' %> πʶҦ5ˎɽІΦ“̨DŽ/Ѡ¬”м̜*ŏͩ 8 ͥ_ų̓ǻUƝΒŰǺ5˦Ê҈ȷěІΦм̜̫XË˕ž̛ Ȁ̫ҹҷ/signupŠij 5.9 ȁ͈ ij 5.9 “˕ž”ҹҷ /signup 174 ̓Ĵ˜ЍưВþTѫѐ5 $ bundle exec rspec spec/ ͩ 5 ͥ ŰĦƞƎ 5.5 ŒĘ ʄͥǻU$ư̛͘ƮŲ)5 Aʠƻ0ІΦ5 Aм̜ʄ2Ã̫Ź_ɜ̫Œųї͈o͘Ʈ ˦Ê ̛Ȁ˕ž̨DŽěѠ¬̫Éι˼Ċų̓ǎàÉιɼĊɮ–˕̛ȀÉι Šʔn̛ Git ̫Џ̓ĴlưВȏʄͥȁ‚̫ɌÌćƫ»%¯Ɋ $ git add . $ git commit -m "Finish layout and routes" $ git checkout master $ git merge filling-in-layout іþTȏR̀ȹѡ» GitHub  $ git push ɼĊlþTȏư̛͘ƮѸΧ» Heroku $ git push heroku ˼ĊĴ“̚C̒Ň” Ɗnj»5 þTѓϡ̫͈o͘Ʈ $ heroku open Šʔѯ»ҕӄѓϡ $ heroku logs Ѝ̽n̛ Heroku ̫ɥǒɘVȵҌĈɩ͆wlƝΒ‚5R̀ 2.17 ȁ͈̫ɌÌ 5.6 Ė 1. ˜ЍҴǙҹҷ̫R̀ 5.28 ƝΒͮÔ5cіɽ AѿŎ̫ĵɟRSpec ȼp5 ͑ĉ$“•D̛oshared example”̫шÍÉιþT˟ҦїAѿŎȧ˽R̀ 5.36 ̫Džƻ˦ÊˎɽΠ¢̫“ƣÍ”ҹҷ“–:” ҹҷě“γ΀”ҹҷ̫˜Ѝ˕DZR̀ 3.31 ̛»̫ let ɟ˓üϬҲϬƊ_̛ȦŲ̫~µƶ ƎѸõҀ oŠƼ̛їõҀɩ̷ˀ*ųoõҀüĴЭ~ɩȃϧµƶ 175 2. ǼЄlƝΒ˕DZ»5žƞƎ ҈ȷ̫˜Ѝü˜Ѝ5м̜ІΦήˎɽ˜Ѝ҈ȷɮčȦċ5ʵ̫͆ҹ ҷų̓ї˜Ѝ̫ɟ˓* ɮn̛ RSpec үǺ˜Ѝ ̫ visit ě click_link ®ɕʑR̀ 5.37 ̫˜ЍʌӎЈ ҈ȷ̫ĵĸɮčʵ͆ 3. Ϭn̛R̀ 5.27 ̫ full_title ɟ˓ûŏΠ¢ ̛o˜ЍêʌѶƣÍɟ˓þì˽R̀ 5.38ҲϬɞƶ spec/helpers ̴DŽě application_helper_spec.rb ɘV˼Ċ̛R̀ 5.39 ̫R̀ƃ˜Ƽ‘require˜Ѝѓϡ˜ЍӎЈ ɞR̀ɮčþTʵƤn̛˕DZ R̀ 5.38 ̛» 5ʵ³ϥэƻregular expression6.2.4 ω_‚KΑdzН Alex Chaffee ̫ƶϿƫȼp5ʄӄ̛» ̫R̀ R̀ 5.36 ̛ RSpec “•D̛o”ʌ˟ҦѿŎ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do subject { page } shared_examples_for "all static pages" do it { should have_content(heading) } it { should have_title(full_title(page_title)) } end describe "Home page" do before { visit root_path } let(:heading) { 'Sample App' } let(:page_title) { '' } it_should_behave_like "all static pages" it { should_not have_title('| Home') } end describe "Help page" do . . . end describe "About page" do . . . end describe "Contact page" do 176 ͩ 5 ͥ ŰĦƞƎ . . . end end R̀ 5.37 ˜ЍƞƎ ̫҈ȷ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do . . . it "should have the right links on the layout" do visit root_path click_link "About" expect(page).to have_title(full_title('About Us')) click_link "Help" expect(page).to # fill in click_link "Contact" expect(page).to # fill in click_link "Home" click_link "Sign up now!" expect(page).to # fill in click_link "sample app" expect(page).to # fill in end end R̀ 5.38 ž full_title ƣÍɟ˓̫˜Ѝ spec/helpers/application_helper_spec.rb require 'spec_helper' describe ApplicationHelper do describe "full_title" do it "should include the page title" do expect(full_title("foo")).to match(/foo/) end it "should include the base title" do expect(full_title("foo")).to match(/^Ruby on Rails Tutorial Sample App/) end 177 it "should not include a bar for the home page" do expect(full_title("")).not_to match(/\|/) end end end R̀ 5.39 n̛ ͮÞ̫Ƽ̛Rɻ˜Ѝ ̫ full_title ɟ˓ spec/support/utilities.rb include ApplicationHelper 178 ͩ 6 ͥ ̛Ȁʬľ ĉ 6 ć ö®às ͩ 5 ̫ͥʃƍǻUµƶ5 #ɩ̛̫Ȁ˕žҹҷ5.4 ωʄɓ͘ȷʌ̫īͥ_ѧʷ!Żїҹҷ̫Éι ͩ –Ҏ̫ʷӏɮ$Τ̛̫ͤȀµƶ ɕȰʬľTîū‡ɕȰ̫ɟƻͩ 7 ͥ_ų̛̓Ȁ˕žÉιƫµƶ ̛ȀЬəҹҷ̛Ȁι˕žĊǻUƊϬų̨̓DŽěѠ¬Éιͩ 8 ͥͩ 9 ͥ9.2.1 ω_KΑŠhwȓҹҷ ѵϧɣʈҤ̫GĕЇҕͩ 6 ͥ»ͩ 9 ̫ͥŹΔćĴ гǻUƊƷò¬5 ÉιŰɗ̫ Rails ̨DŽě̛Ȁ ӎЈ΀ΙǼЄl̾ѱƝΒɽNjŐƷòş5̫ Rails ̛ȀӎЈɟʥɡ˕ 6.1ϵѽ5$H(πƅĴ¶ŭҜʼοƜ Ʒò ̛ȀӎЈ΀ΙǼЄɮɹş̫ɟ˓ ї ͥNjґŹNjŐl0Є_ϳnjɽAȨǽǝ̆ºɮžɕȰʬľɞȂʌЗѐŭŰʄͥĊǻU_Ʒò¬ þĴųҠư̛͘Ʈ n̛̫΀ΙÓȠɕȰӎЈū‡ě̛ȀxǠϓóͪÉι Íå 6.1ıĩ•ŸYö®źľđĚ Ńʄȁɽ̫ Web ư̛͘Ʈѹ_ҲϬʗ̨͑DŽě̛ȀӎЈ΀ΙȁT Web ʤʖœѹɽNjŐӎЈ΀Ι̫ų̓ɟ ʥRails ǃ˼0oơ̆ȀӎЈîȲʈ΀ΙɽNjŐÓȠ ClearanceAuthlogicDevise ě CanCanіɽ AɮҒ҂ž Rails ̫Ń: OpenID ě OAuth Ʒò̫΀ΙȁTlζŲƊ_ҕ$H(іϬѿŎ¼ѭу ũ$H(̶ȷ̛̓ɽ̫ϵ¤ɟʥήϬοƜƷòĖ ӊųоƝΒЈɪœŐɕΤ̛̫ͤȀӎЈ΀ΙѹϬžͩɟR̀Ư‚ AŲ¼ěyɌїLjLjˀѿɞƷò ӎЈ΀Ι̫ƘkҀіœŸέ̓ɽ̫ɟʥƊˆ “Ә̰”lɣ˓5ϵ˜ »ƱɽAH(ÉιήοƜ Ʒò̫ЏƊιɹş̫̕ϵų̫̓ѐ͘ήRails ɼє̫ɹɞìϮ6.3 ωnƷòӎЈ΀ΙõnjNjͮÞ ɼĊŠʔĊΛƷòϬ̛ͩɟR̀Ư̫Џĭ$οƜƷòѐȁTlþTɹş̫̕ϵ˜ų̓ѐ͘t:Ų¼ Éι ě*À ʠŠʔl ̶n̛ Git ‚̂ʄȸ¼̓Ĵɼş$ʄͥµƶ M¯Ɋ $ git checkout master $ git checkout -b modeling-users ͩ ĚSɮϬ͆wŌĴ%¯Ɋїʠµƶ̫ modeling-users M¯Ɋȃ_Ń: master ¯Ɋ̫ǃÀ̉ǙŠ ʔlƝΒŌĴ%¯Ɋ̫ЏþTнѐͩ ĚS 179 6.1 User às ȷʌ̫ͥɼΐɮϬų̓Τ̫ͤ“˕ž”ҹҷʐǜijŠij 6.1 ȁ͈Ĵʶ*ÀǻUϬϵ¤̛Ȁ̫ū‡ҕӄĭ $̓Ĵіˎɽĵɟū‡̛ȀxǠȁTų̛̓Ȁ˕žÉι̫ͩ ʷɮµƶ ɕȰΔʐϓóƫū‡̛Ȁ̫x Ǡ ij 6.1 ̛Ȁ˕žҹҷ̫ʐǜij Ĵ Rails ɕȰʬľ̫әϻɕȰΔʐý‚ʬľmodelMVC ̫ MìϮ1.2.6 ωRails $ϵ¤ɕȰȥ'Ôȼ p̫әϻϵ¤ɟʥɮn̛ɕȰƯū‡ҲϬґʁn̛̫ɕȰěɕȰƯB=әϻ̫R̀Ưɮ Active Record1Active Record ȼp5 ΀²̫ɟ˓þ̶ȷ̛:µƶwūʙБɕȰžПήɣҲn̛–΀ɕȰƯȁ̛̫ΔʐÔʙБД Ϸstructured query language SQL2Rails іɊȥɕȰƯю͗migrationÉιŠЄǻUn̛Ή Ruby R̀Ų )ɕȰΔʐή̛ŭ1ɕȰŲ)ДϷdata definition language, DDLActive Record ȏlěɕȰƯƏےҫƷ 5ʄɓ͘Ʒò̫ư̛͘ƮĴʄĵn̛̫ɮ SQLite ɕȰƯѸΧĊn̛ PostgreSQL ɕȰƯ̜ Heroku ȼpìϮ 1.4 ωїƊƼ‘5 ɹˤƏʭ̫ЏӄѶƊɮĴĈ̫̒Ň åtn̛̫ɮĈͶľ̫ɕȰƯǻU0ɣ Ҳ–Ǐ Rails ɮŠhū‡ɕȰ̫ 1. Active Record їĉŪʌο“Active Record ʬƻ”¬ο Martin Fowler ̫[ư̛ʖʐʬƻ 2 2. SQL Йk ess-cue-ellѐ0ΒƤЙk sequel 180 ͩ 6 ͥ ̛Ȁʬľ 6.1.1 Ç·œőĄ ĬҾ  4.4.5 ω̫ŹĴǻUοƜµƶ̫ User Ͷ ƝΒn̛5̛ȀžПɽ name ě email ƓǝѶɮ Njɽ̛̫oũcˎɽų̓ȥ'ǝɼ–Ҏ̫Ϭˇ Ĵ Rails ȸ¼ÿ µƶ̛̫ȀžПѠ¬ȸ¼ÿĊƊ_˟ŗ ʄω̴̫̫Ɗɮµƶ ̛Ȁʬľȥ'Ôū‡ɕȰ ě 4.4.5 ω ̫ User Ͷ ʠǻUơ̑ȀʬľІϹ$üɽƓǝ¯ºɮ name ě emailEmail ĵĸ͙Ċ_ k$̛Ą̏DŽ̛̫Ȁĉ36.3 ω_˦Ê̛Ȁź̷̀–̫ƓǝR̀ 4.9 n̛ Ruby ̫ attr_accessor ɟ˓µƶ 5їƓǝ class User attr_accessor :name, :email . . . end Ĵ Rails ̛їʠŲ)ƓǝŠÀҷȼ»̫Rails әϻn̛–΀ľɕȰƯū‡ɕȰɕȰƯ ̫ϥtableɮ̜ ЁDŽϡrow΍Ǻ̫ʿϡ ѹɽ̷ư̫ɕȰƓǝ²columnoŠϬū‡̛Ȁ̫ĉŪě Email ĵĸǻUϬ µƶ users ϥϥ Óď name ²ě email ²ʿ ϡRϥ ̛ȀїʠĚĉ²Active Record ƊιȌ»̛ ȀžП̫Ɠǝ5 ϽǻU̺  Active Record ɮǚ(Ȍ»̫ŠʔҷїAϼЅžlʌЗŕȗП5ИίǏ̫̺ë6.1.3 ωĴ ȸ¼ÿ ̫Ɉk͈oTîij 6.3 ěij 6.6 ̫ɕȰƯ˝ϲĩǾijưВ_Ͻlɹ˧ʪ̫̕ϵїAŹR̀ 5.29 n̛ҷ̫ĚS̚Ǻ5 Users ȸ¼ĩě new Ìk $ rails generate controller Users new --no-test-framework µƶʬľþTn̛Ͷb̫ĚS generate modelR̀ 6.1 ȁ͈$̚Ǻ User ʬľTî name ě email Ɠǝȁ ̛̫ĚS R̀ 6.1 ̚Ǻ̛Ȁʬľ $ rails generate model User name:string email:string invoke active record create db/migrate/[timestamp]_create_users.rb create app/models/user.rb invoke rspec create spec/models/user_spec.rb ˕DZě̚Ǻȸ¼ĩ̫ĚS1ǭĈʬľ̫ĉŪɮÞɕ ȸ¼ĩɮ Usersήʬľɮ UserǻUȼp5þѥ ̫ìɕ name:string ě email:stringĔЊ Rails ǻUҲϬ̫ƓǝɮH(TîĆο̫ͶľѹɮŪ ͨ"lþTȏїìɕR̀ 3.4 ěR̀ 5.29 ̫Ìkĉ͖žˀ ̺̺ɽH(Ĉ 3. ȏ Email k$̛ȀĉTĊŠʔҲϬě̛Ȁγ΀Ɗɟt5 181 R̀ 6.1 ̫ generate ĚSƢʌ̫Δʔ* ɮµƶ5 ɕȰƯю͗ɘVю͗ɮ ͑ͻ͆yɌɕȰƯΔʐ̫ɟ ƻþTʢȰҲˇyɌɕȰʬľʄo User ʬľ̫ю͗ɘVɮ̶ȷѫѐ generate model ĚS̚Ǻ̫ю͗ɘ V_µƶ users ϥÓď²å name ě emailŠR̀ 6.2 ȁ͈ǻU_Ĵ 6.2.5 ωTî 6.3 ωKΑŠh Ȃ̵ƶю͗ɘV R̀ 6.2 User ʬľ̫ю͗ɘVµƶ users ϥ db/migrate/[timestamp]_create_users.rb class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.string :name t.string :email t.timestamps end end end ˕DZ ю͗ɘVĉ̫ÀҷɽɩҖǿtimestampїɮВɘVϧµƶɩ̫ɩҖɨʁю͗ɘVĉ̫ÀΞɮѨ ň̫ɕŪĴÝkĮҙ ŠʔŐΠ͘Gĕ̚Ǻ5̷ĈƮĂ̫ю͗ɘVƊþι_ò̚£͟Ҧҵю͗ɘVĴĈ ͓҃̚Ǻї͑Ƅʫ̐8Vò̚5č³n̛ɩҖǿŃʄþTѵ£̫͟ò̚ю͗ɘV̫R̀ ɽ ĉ$ change ̫ɟ˓їɟ˓Ų)ϬžɕȰƯ‚H(ɈkR̀ 6.2 change ɟ˓n̛ Rails ȼp̫ create_table ɟ˓ĴɕȰƯ ɞƶ ϥ̛ʌū‡̛ȀɕȰcreate_table Ċк̽ ĻȦŲ5 Ļ ìɕ tRϥїϥžПĴĻ create_table ɟ˓ѫѐ t žПµƶ5 name ě email ²Ĺ$ string Ͷľ4їѾn̛̫ϥĉɮŎɕDžƻusersѐʬľĉɮÞɕDžƻUserїɮ Rails Ĵ̛Ћ̫ ·Ųåʬľϥ̫̓ɮÞ̛Ȁ̫̆ǝήɕȰƯϥæū‡5NjƠ̋ȀĻ ɼĊ ϡ t.timestamps ɮ ̆ʻ̫ɟ˓Ů_ο̵ƶ²created_at ě updated_atї²¯ºЁDŽµƶ̛Ȁ̫ɩҖǿěɹɞ ̛ȀɕȰ̫ɩҖǿ6.1.3 ω_KΑn̛ї²̫oũїю͗ɘVϥ͈̫ŰɗɕȰʬľŠij 6.2 ȁ͈ ij 6.2 R̀ 6.2 ̚Ǻ̛̫ȀɕȰʬľ ǻUþTn̛Š̫ rake ĚSìϮɡ˕ 2.1ʌȆϡїю͗0ý“ċю͗” $ bundle exec rake db:migrate lþιіЁnjǻUĴ 2.2 ω n̛ѐїĚSͩ ʭѓϡ db:migrate ĚSɩ_ɞƶ db/ development.sqlite3їɮ SQLite5ɕȰƯɘVϋϬʙ̺ɕȰƯΔʐþTn̛ SQLite ɕȰƯ˝ϲĩȄƷ 4. ϬͰ t žПɮǚ(ų̫̓k$ȗПƏ̫ϫǻUɣҲѐՖǏŮ̫™gų̓lüϬ̷xŮþTŰǺȦŲ̫ƘkƊϡ 5 5. SQLite Йk ess-cue-ell-iteѐzɮΒƤn̛ҌЕ̫ЙҸ sequel-ite 182 ͩ 6 ͥ ̛Ȁʬľ db/development.sqlite3 ɘVŠij 6.3 ȁ͈ěij 6.2 ̫ʬľžˀ*Ċl_ò̓ id ²Ĵю͗ɘV ˎɽŲ)Ĵ 2.2 ω KΑѐRails ȏї²k$ϡ̫ġ ʜЉͨ ij 6.3 ̛ SQLite ɕȰƯ˝ϲĩʙ̺´µƶ̫ users ϥ œŐɕю͗ÓȠʄɓ͘ ̫ȁɽю͗ѹɮþѤ̫0ƊɮЗþTѫѐ ͮÞ̫ Rake ĚS“ċю͗”Ʌ҉* À̫ю͗ɈkїĚSɮ db:rollback $ bundle exec rake db:rollback ûŏіɽ Ʌ҉ю̫͗ɟ˓Иʙ̺ɡ˕ 3.2їĚS_Л̛ drop_table ɟ˓ȏ users ϥMɕȰƯ · ҦǻU*ȁTþTї(‚ɮĭ$ change ɟ˓̾ѱ create_table ̫ñɈkɮ drop_tableȁTĬˮɩƊ _̶ȷЛ̛ drop_table ɟ˓ž: Aɣ˓οÌѤт̫ɈkoŠ·Ҧ²ƊιqЯ change ɟ˓5ǻU Ϭ¯ºŲ) up ě down ɟ˓–:ю̫͗ɹ՝ŹИʙ̺ Rails Ȧß ŠʔlȆϡ5ҷ̫ĬˮɈkĴΚΛҘЙ*ÀИŸю͗Ĭʌ $ bundle exec rake db:migrate 183 6.1.2 àsÉ( ǻUKΑ5ǚʠn̛R̀ 6.1 ̚Ǻ̫ю͗ɘVìϮR̀ 6.2µƶ̛ȀʬľĴij 6.3 ̺»5Ȇϡю͗ɈkĊ̫ ΔʔåyɌ5 db/development.sqlite3ɞƶ users ϥƫµƶ5 idnameemailcreated_at ě updated_at ї©²R̀ 6.1 Ĉɩ0̚Ǻ5ʬľɘVʄω̴̫̫Ɗɮʌ̕ϵ їʬľɘV ǻUM User ʬľ̫R̀ЗгʬľɘVūɎĴ app/models ̴DŽĉ$ user.rbїɘV̫ŹNjͮÞ ìϮR̀ 6.3 R̀ 6.3 ´µƶ̫ User ʬľɘV app/models/user.rb class User < ActiveRecord::Base end Ĵ 4.4.2 ω KΑѐclass User < ActiveRecord::Base ̫DZǜɮ User ͶΚȍο ActiveRecord::Base ͶȁT User ʬľƊοÌϓnj5 ActiveRecord::Base ȼp̫Éιǃ˼5ü̾ѱї͑Κȍ–΀ˎH(̛ ǻUƫ̾ѱ ActiveRecord::Base ‚5H(͙ĊǻU_KΑ їͶĴΚΛҘЙ*ÀіɽV8Ϭ ‚ 6.1.3 Ežö®ŠŇ ě ͩ 4 ͥ ʠȶ΂ɕȰʬľǻUn̛̫Ƙ™ɮ Rails ȸ¼ÿĭ$ǻUіǯɌÌɕȰƯȁTǻUϬĴˌ̰ʬ ƻsandbox đÌȸ¼ÿ $ rails console --sandbox Loading development environment in sandbox Any modifications you make will be rolled back on exit >> Šȼ͈xǠȁЗ“Any modifications you make will be rolled back on exit”Ĵˌ̰ʬƻn̛ȸ¼ÿѠ¬ǃÀ_Џ ĊžɕȰƯ‚̫ȁɽɌÌѹ_Ĭǂ»êʌ̫̉Ǚ 4.4.5 ω ̫ȸ¼ÿ_ЏҲϬȂÌÊцοƜΠ¢̫ User Ͷȃιn̛ User.new µƶ̛ȀžПµƶʬľĊǧ¥ Ɗ ʠ54.4.4 ω KΑѐRails ȸ¼ÿ_οÌÊц Rails ̒Ňǃ˼0_οÌÊцʬľ0ƊɮЗ̓ĴɣҲ Êцӆŏ̫R̀ƊþT̶ȷµƶ̛ȀžП5 >> User.new => # ѝ̫̫ȸ¼ÿɯ͈5 ̛ȀžП̫әϻ~ Šʔ$ User.new ȦŲìɕžП̫ȁɽƓǝ~ѹɮ nilĴ 4.4.5 ω οƜΠ¢̫ User ͶþTȷô  Hash ìɕ̛ʌ¶ţÔžП̫Ɠǝї͑ɟƻɮô Active Record đò̫Ĵ Active Record 0þTn̷̛Ĉ̫ɟƻ ȦŲ¶ţ~ 184 ͩ 6 ͥ ̛Ȁʬľ >> user = User.new(name: "Michael Hartl", email: "mhartl@example.com") => # ǻU̺» name ě email Ɠǝ̫~ѹƝΒІŲ5 Šʔʙ̺Ʒòɥǒ̫Џ_ò̓ˎɽH(ɞŹїɮĭ$ User.new ɟ˓ƫˎɽɌÌɕȰƯüɮĴū µƶ 5 ̛ȀžПŠʔϬơ̑ȀžПwū»ɕȰƯ ϬĴ user žПЛ̛ save ɟ˓ >> user.save => true ŠʔwūǺÉsave ɟ˓_ѕĬ true č³ѕĬ false̓Ĵȁɽ̫wūɈkѹ_ǺÉ66.2 ω_̺»wūŗ Х̫oũwūǺÉĊɥǒɘV Ɗ_¬̓ ϡ SQL Дú INSERT INTO "users"Active Record ȼp5 NjŐɟ˓̛ʌěɕȰƯB=ȁTlʢʄҲϬ̶ȷn̛SQL ДúJĊǻ0_KΑ SQL ̷–̫̾ЉŠʔl ǯŭ1 SQLþTʙ̺ɥǒɘV lþι˕DZ»5´µƶɩ̛ȀžП̫ idcreated_at ě updated_at Ɠǝ~ѹɮ nilҷ̺ wū*Ċ ɽH(õÔ >> user => #00:57:46", updated_at: "2011-12-05 00:57:46"> ŠѝR̀ȁ͈id ̫~õǺ 1 5Ѷο̵ƶ̫ɩҖǿƓǝ0õǺ5ǃÀ̫ɩҖ7̓ĴїɩҖǿɮ ʠ̫6.1.5 ω_̺»9έĈ̫ǧ¥ ě 4.4.5 ω ̫ User Ͷ ʠUser ʬľ̫ųo0þTn̛˸ĂϓóƓǝ 8 >> user.name => "Michael Hartl" >> user.email => "mhartl@example.com" >> user.updated_at => Mon, 11 Mar 2013 00:57:46 UTC +00:00 6. Ќέ˕ ĭ$іˎʑɕȰӎЈ 7. lþιž "2013-03-11 00:57:46" їɩҖdz»şŚ$H(kέÜőіĴ¢2Ė ˜ų˼їɩҖǿɮʜ¦Ýɩ Coordinated Universal Time, UTCͶb:ʣʒƋːƩɩGreenwich Mean Time, GMTTɂοΨIJIJŸʜ¦Ȏʅ́͜ȁ ɩҖěӃ̐ă̫ FQA Τҹҕ $H(ʜ¦Ýɩ̫΢¢ɮ UTC ήɮ CUT ͫ ʜ¦ÝɩɮĴ 1970 ƪ̜IJҠ̞xγ̳ ITU̫ŸҾҕĮІϹ̫ITU ϳnjưВn̛ ѫ̛̫΢¢Džƻѵ˥ˡĭ$Ćɟɣ˓эǺ•Љɼΐ ITU ˎɽѼ̛ύ ɘ΢¢ CUT Ǽ˓ɘ΢¢ TUC ήɮȑ ѥȟ5 UTC 8. ˕DZ user.updated_at ̫~ҷЗѐ5їɮ UTC ɩҖ 185 Ĵͩ 7 ͥ _KΑϝ˼ υ1ǭȏµƶěwū¯ǺŠȁ͈̫ʷ¯ºɈkѐ Active Record 0ŠЄǻUn̛ User.create ɟ˓ȏїʷćǺ ʷ >> User.create(name: "A Nother", email: "another@example.org") # >> foo = User.create(name: "Foo", email: "foo@bar.com") # ˕DZUser.create ̫ѕĬ~ɮ true Ǽ falseήɮѕĬµƶ̛̫ȀžПþ̶ȷЭ~ΖõҀoŠҷͩ 9ĚS ̫ foo õҀ. create ̫ñɈkɮ destroy >> foo.destroy => # ŚǞ̫ɮdestroy ě create ʠѕĬ~ɮ҉ʽ̫žПǻϳnjH(ĵɟ_̛» destroy ̫ѕĬ~ɹŚ Ǟ̫8ǧɮ҉ʽ̫žПіĴū >> foo => # Ѷ(ǻUǚ(̾ѱžПɮč̻̫ϧ҉ʽ5Ė ž:ƝΒwūήˎɽ҉ʽ̫žПǚʠMɕȰƯ ϓóĖ ϬĬͫї AҕӄǻUϬŭ1Šhn̛ Active Record ʙƠ̏ȀžП 6.1.4 Ú³ö®ŠŇ Active Record $ʙȌžПȼp5ş©͑ɟ˓ǻUϬn̛їAɟ˓ʌʙȌ´µƶ̫ͩ ̛ȀĈɩ0ӎЈ ͩ ̛Ȁfooɮčϧ҉ʽ5̺ іūĴ̛̫Ȁ >> User.find(1) => # ǻUơ̑Ȁ̫ id `ѨΖ User.find ɟ˓Active Record _ѕĬ id $1 ̛̫ȀžП ҷʌ̺  id $ 3 ̛̫ȀɮčіĴɕȰƯ >> User.find(3) => #ActiveRecord::RecordNotFound: Couldn't find User with ID=3 186 ͩ 6 ͥ ̛Ȁʬľ ĭ$Ĵ 6.1.3 ω ҉ʽ5̛ͩȀȁT Active Record ɣ˓ĴɕȰƯ Ȍ»Ȓ¬5 ƸƤЗɪĴʙȌѐ͘ ¬̓5ҕӄĭ$ id ūĴȁT find ɟ˓ȃ_Ȓ¬ ActiveRecord::RecordNotFound ƸƤ9 Ҧ5 find ɟ˓*ŏActive Record іɊȥȦŲƓǝʌʙƠ̏Ȁ >> User.find_by_email("mhartl@example.com") => # find_by_email ɟ˓ɮ Active Record ʢȰ users ϥ ̫ email ²οÌŲ)̫lþι̎»5Active Record і Ų)5 find_by_name ɟ˓M Rails 4.0 ƷţѫѐƓǝʙȌЁDŽȹϐ̫‚˓ɮn̛ find_by ɟ˓Ɠǝ~ T Hash Džƻ`‘ >> User.find_by(email: "mhartl@example.com") => # ĭ$ǻU_ȏ Email ĵĸǃǺ̛Ȁĉn̛ȁTĴų̛̓Ą̏DŽÉιɩї͑ʙƠ̏Ȁ̫ɟƻ_Njɽ̛ìϮͩ 7 ͥl0Є_ȘǏŠʔ̛ȀɕҀѐŐn̛ find_by ̫ɐ̐ӑ8ų̫͆ŠʶǻU_Ĵ 6.2.5 ωKΑїҕ ӄTîϵ¤ɟ˓ån̛ɕȰƯ΂Ƽ ɼĊǻUіϬKΑ©Ƥ̛̛̫ȀʙȌɟ˓ӊɮ first ɟ˓ >> User.first => # Njɪɯfirst _ѕĬɕȰƯ ̫ͩ ̛Ȁіɽ all ɟ˓ >> User.all => [#, #] all ɟ˓_ѕĬ ɕ΍ÓďɕȰƯ ̫ȁɽ̛Ȁ 6.1.5 ÑËö®ŠŇ µƶžПĊ υѹ_јϡɹɞɈkɹɞɽ͑Ńʄ̫ɟƻ˜ ǻUþT¯º$ĆƓǝЭ~Ĵ 4.4.5 ω Ɗɮї(‚̫ 9. ƸƤěƸƤŌ̕ɮ Ruby ДϷ̫ӑΈÉιʄ2Ńʄ_ˠîї9έѐƸƤɮ Ruby ДϷ NjѿϬ̫ Ѹ¯ƶϿlѫѐ 1.1.1 ω ȹϐ̫2͵ŭ1 187 >> user # Just a reminder about our user's attributes => # >> user.email = "mhartl@example.net" => "mhartl@example.net" >> user.save => true ˕DZɼĊ ĚSɮǐҽ̫ǻUϬȏɌÌ¢‘ɕȰƯǻUþTȆϡ reload ĚSʌ̺ ˎwū̫ЏɮH( ǧ¥reload ĚS_n̛ɕȰƯ ̫ɕȰѿɞÊцžП >> user.email => "mhartl@example.net" >> user.email = "foo@bar.com" => "foo@bar.com" >> user.reload.email => "mhartl@example.net" ̓ĴǻUƝΒɹɞ5̛ȀɕȰŠĴ 6.1.3 ω ȁЗο̵ƶ̫ѶɩҖǿƓǝƊ ʠ5 >> user.created_at => "2013-03-11 00:57:46" >> user.updated_at => "2013-03-11 01:37:32" ɹɞɕȰ̫ͩ9͑Ƥ̛ɟƻɮn̛ update_attributes ɟ˓ >> user.update_attributes(name: "The Dude", email: "dude@abides.org") => true >> user.name => "The Dude" >> user.email => "dude@abides.org" update_attributes ɟ˓þȷô ȦŲžПƓǝ̫ Hash k$ìɕŠʔɈkǺÉ_ȆϡɹɞěwūĚ SwūǺÉɩѕĬ~$ true˕DZŠʔXh ɕȰӎЈŗХ5oŠū‡ЁDŽɩҲϬź̀_Ĵ 6.3 ωų ̓update_attributes ɈkƊ_ŗХŠʔϬɹɞÞƓǝИn̛ update_attributeїʠƊιнѐ ӎЈҤ¼5 >> user.update_attribute(:name, "The Dude") => true >> user.name => "The Dude" 188 ͩ 6 ͥ ̛Ȁʬľ 6.2 ö®Ç·źľ 6.1 ωµƶ̫ User ʬľ̓ĴƝΒɽ5þTn̛̫ name ě email ƓǝѐÉιіNjͮÞ XhŪͨ"ÓȠ͝Ū ͨ"ѹþTn̛ĉŪě Email ĵĸ̫ʣƻɯ˼ϬŎʇ AoŠname ưВɮ̩̫͝email ưВͨć Email ĵĸ̫̆ŲʣƻήǻUϬȏ Email ĵĸǃǺ̛Ȁĉ̛ʌ̨DŽѶ(ʗ Email ĵĸĴɕȰƯ ƊưВɮ ġ ̫ ǟ*name ě email ɮH(Ūͨ"ѹþTȷô̫ǻUϬž9έþȷô̫~‚Ҥ¼Active Record ɮѫѐɕ ȰӎЈʆ¼validationų̓ї͑Ҥ¼̫ʄωǻU_KΑ©͑Ƥ̛̫ɕȰӎЈ ūĴǝґƴʣƻěġ ǝĴ 6.3.4 ωі_KΑû ͑Ƥ̛̫ɕȰӎЈ 9ʭ͆ϻ7.3 ω_̺»ŠʔȼB5ćϬˇ̫ɕȰɕȰӎЈ ʆ¼_ɯ͈ ANjɽ̛̫ҌЕȼ͈xǠ 6.2.1 ö®àsæŀ ěƷò͈o͘Ʈ̫˜PÉι ʠǻU_n̛ TDD ɟƻ˦Ê User ʬľ̫ɕȰӎЈÉιĭ$̚Ǻ User ʬľɩˎɽ ȦŲ --no-test-framework ɢʜěR̀ 5.29 ĈR̀ 6.1 ̫ĚS_οÌ$ User ʬľ̚Ǻ ¶ţ̫˜ ЍɘVѐɘV ˎɽH(ŹìϮR̀ 6.4 R̀ 6.4 ©+ˎH(Ź̫ User ʬľ˜ЍɘV spec/models/user_spec.rb require 'spec_helper' describe User do pending "add some examples to (or delete) #{__FILE__}" end ѝR̀n̛5 pending ɟ˓ȼ͈ǻUưВΠ¢ A̻ʵɽ̛̫˜ЍǻUþT¦ō ͝“˜ЍɕȰƯ”˼Ċ ѓϡ User ʬľ̫˜Ѝ̺ ̓Ĵ̫ǧ¥ $ bundle exec rake db:migrate $ bundle exec rake test:prepare $ bundle exec rspec spec/models/user_spec.rb * Finished in 0.01999 seconds 1 example, 0 failures, 1 pending Pending: User add some examples to (or delete) /Users/mhartl/rails_projects/sample_app/spec/models/user_spec.rb (Not Yet Implemented) ĴœŐɕ΀Ι ɽNJų̫̓˜Ѝѹ_ɯ͈$ӗχK:ѫѐΝχěŗХΆχ*Җ їɮǻUͩ ʭ̺»µƶ“˜ЍɕȰƯ”̫ʵ͆ĚS 189 $ bundle exec rake test:prepare їĚS_ȏ“ƷòɕȰƯ” db/development.sqlite3 ̫ɕȰʬľŎ¼»“˜ЍɕȰƯ” db/test.sqlite3 Ȇϡю͗ĊNjŐGΒƤѹ_ǓЁȆϡї Rake XËή“˜ЍɕȰƯ”ΒƤ_ȭĺҲϬіêŠʔ˜Ѝ ¬̓5ϒĉ˜š̫ҕӄþTȆϡ rake test:prepare ̺ιčϵ¤ ǻU_ȧ˽ȼ͈̫ƶϿΠ¢ A RSpec ˜Ѝ̛oŠR̀ 6.5 ȁ͈ R̀ 6.5 ҂ž :name ě :email Ɠǝ̫˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do before { @user = User.new(name: "Example User", email: "user@example.com") } subject { @user } it { should respond_to(:name) } it { should respond_to(:email) } end before ĻĴR̀ 5.28 ̛ѐ_ĴĆ˜Ѝ̛o*ÀȆϡĻ ̫R̀ʄo їĻ̫k̛ɮ$ User.new `‘ ć˓̫¶ţ Hash ìɕµƶ @user ųoõҀȷʌ̫ subject { @user } ȏ @user І$їA˜Ѝ̛oәϻ̫˜ЍžПĴ 5.3.4 ω ІŲ̫˜ЍžПɮ page õҀ R̀ 6.5 ̫˜Ѝ̛ož name ě email Ɠǝ̫ūĴǝјϡ5˜Ѝ it { should respond_to(:name) } it { should respond_to(:email) } ˜ųї˜Ѝ̛on̛̫ɮ Ruby ̫ respond_to? ɟ˓їɟ˓þTȷô  Symbol ìɕŠʔžПþT ĞưȦŲ̫ɟ˓ǼƓǝƊѕĬ trueč³ѕĬ false $ rails console --sandbox >> user = User.new >> user.respond_to?(:name) => true >> user.respond_to?(:foobar) => false 190 ͩ 6 ͥ ̛Ȁʬľ Ĵ 4.2.3 ω KΑѐRuby n̛ҕĂʜɪѕĬ~ɮƞƆ~̫ɟ˓їA˜Ѝn̛5 RSpec –:ƞƆ~̫·Ų ȁTŠ̫R̀ @user.respond_to?(:name) Ĵ RSpec þT¢Ǻ it "should respond to 'name'" do expect(@user).to respond_to(:name) end ĭ$ȦŲ5 subject { @user }ǻUіþT¢ǺĴ 5.3.4 ω ̛ѐ̫ÞϡDžƻ it { should respond_to(:name) } $ User ʬľ˦Êɞɟ˓ǼɞƓǝɩþTѼ̛ї͑˜Ѝɟƻήn̛ї͑ɟƻіι˧ɳ̫²¬ User ųožПþT Ğư̫ȁɽɟ˓ ĭ$ǻUÀҷƝΒȆϡ rake test:prepare ĚS¦ōş5“˜ЍɕȰƯ”ȁT˜ЍưВɮѫѐ̫ $ bundle exec rspec spec/ 6.2.2 źľ‚oª ūĴǝӎЈͯɮɼŃʄ̫ӎЈ5ŮüɮʨʙΖŲ̫ƓǝɮčūĴʄωǻUƊ_͆wĴ̛Ȁū‘ɕȰƯ*Àĉ Ūě Email ĵĸŪʼѹɮūĴ̫7.3.3 ω_KΑŠhȏїҤ¼ư̛Ĵµƶ̛Ȁ̫˕žϥÞ  ǻUʌΠ¢ʨʙ name ƓǝɮčūĴ̫˜Ѝϝ˼ TDD ̫ͩ ʷɮ¢ ŗХ˜ЍìϮ 3.2.1 ωѐʶɩ ǻUіˎɽے̕ϵɕȰӎЈɮǚ(ų̫̓ɣ˓Π¢ćѢ̫˜ЍȁTǻUɵɩȏɕȰӎЈÊјʌĴȸ¼ÿ ųɈ ̕ϵ ӎЈʆ¼˼ĊǻU_ȏӎЈR̀˕ѽȳΠ¢ŗХ˜ЍŸȏ˕ѽëȳ̺ ˜Ѝɮč іɮþTѫѐ̫ї(‚žїʠͮÞ̫˜ЍʌЗþιɽ˸Ƅӄœ‚ѐǻϮѐNjŐ“ͮÞ”̫˜Ѝƫˎɽʨʙ̻ʵ Ϭ˜Ѝ̫ŹϬwЈ˜Ѝʨ˜̻ʵҲϬʨ˜̫ŹɼşОǵ ˸ї͑Ê˕ѽ̫ɟ˓Ĵ$ˎɽ˜Ѝ̫ư̛͘ ƮΠ¢˜Ѝɩ0ΒƤ̛» ӎЈ name ƓǝɮčūĴ̫ɟ˓ɮn̛ validates ɟ˓`‘ presence: true ìɕŠR̀ 6.6 ȁ͈ìɕ presence: true ɮüɽ ‹΁̫þѥ Hash ìɕǻUĴ 4.3.4 ω KΑѐŠʔɟ˓̫ɼĊ ìɕɮ Hash ̫ЏþT̹̣ Hash ̫ϊȠĂŠ 5.1.1 ω ȼ»̫їʠ̫þѥ Hash Ĵ Rails NjɱѰ R̀ 6.6 ӎЈ name Ɠǝ̫ūĴǝ app/models/user.rb class User < ActiveRecord::Base validates :name, presence: true end R̀ 6.6 ̺гʌNj͋Ś˜ų validates üѐɮ ɟ˓ήƝÊȠĂĊͪɐ̫R̀Š 191 class User < ActiveRecord::Base validates(:name, presence: true) end ҷĴȸ¼ÿ ̺ $ User ʬľ˦ÊїӎЈ*Ċ̫ɐʔ 10 $ rails console --sandbox >> user = User.new(name: "", email: "mhartl@example.com") >> user.save => false >> user.valid? => false user.save ̫ѕĬ~ɮ falseЗɪū‡ŗХ5ɼĊ ĚSn̛5 valid? ɟ˓ŠʔžПˎɽѫѐXDZ ӎЈƊ_ѕĬ falseŠʔ’ѸӎЈѹѫѐ5³ѕĬ trueїoũüɽ ӎЈȁTǻU̾ѱɮĠӎЈ ŗХ5ѐ̺ ŗХ̫ȼ͈xǠіɮ_ɽ˸ɋϓ̫ >> user.errors.full_messages => ["Name can't be blank"] ҌЕȼ͈xǠɶ͈5 Rails ƓǝūĴǝӎЈn̛̫ɮ blank? ɟ˓Ĵ 4.4.3 ω̫ʃƍ̛ѐїɟ˓ ̓ĴʌΠ¢˜Ѝ̛o$5wЈ˜ЍɮŗХ̫ǻUϬȏӎЈ̛»̫R̀˕ѽȳŠR̀ 6.7 ȁ͈ R̀ 6.7 ˕ѽȳӎЈR̀wЈ˜ЍɮŗХ̫ app/models/user.rb class User < ActiveRecord::Base # validates :name, presence: true end žūĴǝӎЈ̫˜Ѝ̛oŠR̀ 6.8 ȁ͈ R̀ 6.8 ӎЈ name Ɠǝ̫ŗХ˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com") end subject { @user } 10. Šʔȸ¼ÿ ĚS̫ъ¬ˎH(ųҠDZ)ǻƊ_̹̣ȳoŠ User.new ̫ъ¬ 192 ͩ 6 ͥ ̛Ȁʬľ it { should respond_to(:name) } it { should respond_to(:email) } it { should be_valid } describe "when name is not present" do before { @user.name = " " } it { should_not be_valid } end end Šїɞʑ̫˜Ѝɮ$5wЈ˜Ѝ̫’ҷ͆w @user žПƷţɩɮć˓̫ it { should be_valid } їɮ 6.2.1 ω KΑ̫ RSpec žƞƆ~·Ų̫í ųo üϬžПþTĞưѕĬ~$ƞƆ~̫ɟ˓ foo?Ɗɽ žư̫ be_foo þTĴ˜Ѝ n̛ȁTĴʄo ǻUþTȏŠ̫˜Ѝ @user.valid? ¢Ǻ it "should be valid" do expect(@user).to be_valid end ě*À ʠĭ$ȦŲ5 subject { @user }ȁTƊþTn̛ÞϡDžƻ5 it { should be_valid } ͩ9˜Ѝ̛oơ̑Ȁ̫ĉŪІ$ć˓̫~͝ʣ˼Ċ˜Ѝ @user žПɮčɮć˓̫ describe "when name is not present" do before { @user.name = " " } it { should_not be_valid } end їʼR̀n̛ before Ļơ̑Ȁ̫ĉŪІ$ ć˓̫~͝ʣ˼Ċʨʙ̛ȀžПɮč$ć˓̫ ̓ĴlþT̺ ˜ЍɮčɮŗХ̫ $ bundle exec rspec spec/models/user_spec.rb ...F 4 examples, 1 failure 193 ̓ĴëȳӎЈR̀À̫˕ѽȏR̀ 6.7 õĬR̀ 6.6˜ЍƊþTѫѐ5 $ bundle exec rspec spec/models/user_spec.rb ... 4 examples, 0 failures ȷ̽ǻUіϬӎЈ Email ĵĸ̫ūĴǝ˜ЍR̀ěž name Ɠǝ̫˜ЍͶbìϮR̀ 6.9 R̀ 6.9 ž email ƓǝūĴǝ̫˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com") end . . . describe "when email is not present" do before { @user.email = " " } it { should_not be_valid } end end ӎЈ̫ų̓©+0 ʠŠR̀ 6.10 ȁ͈ R̀ 6.10 ӎЈ name ě email Ɠǝ̫ūĴǝ app/models/user.rb class User < ActiveRecord::Base validates :name, presence: true validates :email, presence: true end ̓Ĵȁɽ̫˜ЍưВѹþTѫѐ5ǻU0ƊŰǺ5ūĴǝӎЈ 6.2.3 Ũźľ ǻUƝΒž User ʬľþȷô̫ɕȰ‚5 AҤ¼̓Ĵǐҽ$̛Ȁȼp ĉŪѐǻUưВ‚̫ɹј ʷ̛ Ȁ̫ĉŪ_Ĵ͈o͘Ʈ ɯ͈ȁTɼşҤ¼ Ů̫Ūͨґƴɽ5 6.2.2 ω̫Ń̈́ї ʷƊͮÞ5 ǻUʌΠ¢˜Ѝɼœґƴƫˎɽˀч͒ŭ̫ɟ˓ʌѥŲǻUƊn̛ 50 k$ґƴ̫ҤĎѶ(ǻUƊϬ͆ w 51 Ūͨдґ5ìϮR̀ 6.11 R̀ 6.11 žĉŪґƴ̫˜Ѝ spec/models/user_spec.rb 194 ͩ 6 ͥ ̛Ȁʬľ require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com") end . . . describe "when name is too long" do before { @user.name = "a" * 51 } it { should_not be_valid } end $5ɟtĴR̀ 6.11 ǻUn̛Ūͨ"ћ.̚Ǻ5 ɽ 51 Ū̫ͨŪͨ"Ĵȸ¼ÿ þT̺»ћ.ɮH ( >> "a" * 51 => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" >> ("a" * 51).length => 51 R̀ 6.11 ̫˜ЍưВ_ŗХ$5Ͻ˜ЍѫѐǻUϬ̾ѱǚ(n̛Ҥ¼ґƴ̫ìɕ :lengthTîҤ¼Ҥ ̫ :maximum ìɕӎЈ̷–̫R̀ŠR̀ 6.12 ȁ͈ R̀ 6.12 $ name Ɠǝ˦ÊґƴӎЈ app/models/user.rb class User < ActiveRecord::Base validates :name, presence: true, length: { maximum: 50 } validates :email, presence: true end ̓Ĵ˜ЍưВþTѫѐ5ɤ˼˜Ѝíѫѐ5ǻUϬų̓û ɹ™Ȩǽǝ̫ӎЈ5åž Email ʣƻ̫ӎЈ 6.2.4 Þ¡źľ ž name Ɠǝ̫ӎЈüҲ‚ AͮÞ̫Ҥ¼ƊşXhҵ͝ґƴƄ: 51 Ū̫ͨŪͨ"ƊþTѐ email Ɠ ǝ³ҲϬɹŎʇ̫Ҥ¼̴ÀǻUüɮțΘ̫͝ Email ĵĸʄωǻUϬҤ¼ Email ĵĸͨćƤ̛̫DžƻͶb user@example.com ї͑ їѾǻƯ»̫˜ЍěӎЈɮْÙΨ̫üɮ´´şþTȷôœŐɕ̫ć˓ Email ĵĸƫțΘœŐɕć˓ ̫ Email ĵĸǻU_ž Ać˓̫ Email үćěć˓̫ Email үćјϡ˜ЍǻUn̛ %w[] ʌµƶүć үć ̫‹΁ѹɮŪͨ"DžƻŠҷ̫ȸ¼ÿ_Џȁ͈ 195 >> %w[foo bar baz] => ["foo", "bar", "baz"] >> addresses = %w[user@foo.COM THE_US-ER@foo.bar.org first.last@foo.jp] => ["user@foo.COM", "THE_US-ER@foo.bar.org", "first.last@foo.jp"] >> addresses.each do |address| ?> puts address >> end user@foo.COM THE_US-ER@foo.bar.org first.last@foo.jp Ĵҷїȸ¼ÿ_Џ ǻUn̛ each ɟ˓ìϮ 4.3.2 ωѰè address ɕ΍ ̫‹΁n̛ each ɟ˓þ TΠ¢ AͮÞ̫ Email ʣƻӎЈ˜Ѝ̛oìϮR̀ 6.13 R̀ 6.13 ž Email ʣƻӎЈ̫˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com") end . . . describe "when email format is invalid" do it "should be invalid" do addresses = %w[user@foo,com user_at_foo.org example.user@foo. foo@bar_baz.com foo@bar+baz.com] addresses.each do |invalid_address| @user.email = invalid_address expect(@user).not_to be_valid end end end describe "when email format is valid" do it "should be valid" do addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn] addresses.each do |valid_address| @user.email = valid_address expect(@user).to be_valid end end 196 ͩ 6 ͥ ̛Ȁʬľ end end ŠÀȁЗїA˜ЍƫŰΨѐǻU˜Ѝ5 AƤ̛̫ć˓̫ Email ʣƻoŠ user@foo.COMTHE_USER@foo.bar.orgÓďœ¢Ūʾ±΋TîũŁĉě first.last@foo.jp̛ȀĉɮćǺ̫ first.lastҺΈŁĉɮŪʾDžƻ̫ jpRϥɥʄ0˜Ѝ5 Ać˓̫ Email ʣƻ Ĵư̛͘Ʈ ǻU_n̛ʵ³ϥэƻŲ)ϬӎЈ̫ Email ʣƻ˼Ċѫѐ validates ɟ˓̫ :format ìɕȦ Ųć˓̫ʣƻìϮR̀ 6.14 R̀ 6.14 n̛ʵ³ϥэƻӎЈ Email ʣƻ app/models/user.rb class User < ActiveRecord::Base validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i validates :email, presence: true, format: { with: VALID_EMAIL_REGEX } end ǻUȏїʵ³ϥэƻŲ)$ƤҀ VALID_EMAIL_REGEXRuby ̫ƤҀѹɮTœ¢ŪʾƷŘ̫ VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i validates :email, presence: true, format: { with: VALID_EMAIL_REGEX } n̛ҷ̫R̀þT͆wüɽÖѺїʵ³ϥэƻ̫ Email ĵĸȃɮć˓̫ĭ$ VALID_EMAIL_REGEX Tœ ¢ŪʾƷŘɮƤҀȁT˜~ɮιɌõ̫ Ѷ(їʵ³ϥэƻɮǚ(Π¢¬ʌ̫Ė ʵ³ϥэƻ ̫ɘʄÖѺʬƻɮ̜ͮΌ̫ДϷΠ¢̫NjŐG_ϳnj NjҭЙǷŭ1ŠhΠ¢ʵ³ϥэƻɮ Ғψʅ$5t:̕ϵǻ_ȏ VALID_EMAIL_REGEX ș¯Ǻ©Ļʌ ЂϵŠϥʣ 6.1ȁ͈11Ϭǯϻ̻ŭ1ʵ³ϥэƻǻȹϐn̛ Rubular ʵ³ϥэƻΠщĩŠij 6.4ї Ƙ™Ĵŭ1̫ѐ͘ ɮǐō̫12Rubular Τ̫̠ͤҷNjïşt:Π¢ȁҲ̫ʵ³ϥэƻΤͤ іɽ tȱ̫ ǕѬД˓ìάǻƶϿln̛ Rubular ʌ̕ϵϥʣ 6.1 ̫ʵ³ϥэƻ́ʼЙ̫ŸŐ0ˀĴ Rubular ųɈ ©ʭ˕DZ ŠʔlĴ Rubular ъ‘R̀ 6.14 ̛»̫ʵ³ϥэƻϬȏ \A ě \z ëȳ ϥʣ 6.1 ș¯R̀ 6.14 ÖѺ Email ĵĸ̫ʵ³ϥэƻ ϥэƻ ď) /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i Űɗ̫ʵ³ϥэƻ / ʵ³ϥэƻƷţ \A ÖѺŪͨ"̫ƷŘ 11. ˕DZĴϥʣ 6.1 ǃǻЗ»“Ūʾ”ɩǻ̫ųҠDZǜɮȦ“Ƅ¢Ūʾ”ĭ$Ċҷ̫ i ƝΒȦŲ5ׯœƄ¢̫ʬƻ ȁT0ˎǐϬ¯̫ї(Ύ5 12. Šʔlěǻ ʠϳnj Rubular Njɽ̛ǻƶϿlċkέ Michael Lovitt Ѣǃ̫ȫ̏ A҅TdzНP̫ыÒÐÌ 197 [\w+\-.]+ @ [a-z\d\-.]+ \. [a-z]+ \z / i ϥэƻ ď) ǼŐŪʾÊĂћŪͨǼ˸Ă ÖѺ @ ͨĂ ǼŐƄ¢ŪʾɕŪћŪͨǼ˸Ă ÖѺ˸Ă ǼŐƄ¢Ūʾ ÖѺŪͨ"Δƍ Δʉʵ³ϥэƻ ׯœƄ¢ ij 6.4 ǁœ̫ Rubular ʵ³ϥэƻΠщĩ ҼtЗ Ĵűɟʜ¦ ͆ųɽ ʵ³ϥэƻþTÖѺȁɽ̫ć˓ Email ĵĸcˎǐϬn̛ї(Ŏʇ̫ʵ³ ϥэƻR̀ 6.14 n̛̫ʵ³ϥэƻƊNjş̙πþιˀűɟ̫ɹş13ѐҷ̫ʵ³ϥэƻɽ ΣҨ ιÖѺ foo@bar..com ї͑ɽћΛ˸Ă̫ĵĸyʵї̗̦̫ɟ˓_̢kΌ1ìϮ 6.5 ω 13. l̾ѱČʢȰ Email ʜ¦"Michael Hartl"@example.com ϝɽƼĂě͝ʣc0ɮć˓̫ Email ĵĸNjþǜϿ Ď 198 ͩ 6 ͥ ̛Ȁʬľ ̓Ĵ˜ЍưВѹþTѫѐ5˜ųžć˓ Email ĵĸ̫˜Ѝ ̶ѹɮþTѫѐ̫ĭ$ʵ³ϥэƻNjŹɫ¬ Ҍјϡć˓ Email ʣƻ˜Ѝüɮ$5ʨ˜ VALID_EMAIL_REGEX ɮčþ̛Ѷ(Ɗüà Ҥ¼Ϭų̓5 ͆w Email ĵĸ̫ġ ǝ 6.2.5 iªźľ ͆w Email ĵĸ̫ġ ǝїʠȃιk$̛ȀĉϬn̛ validates ɟ˓̫ unique ìɕȼÀЗɪų̫̓ ѐ͘ ūĴ Njœ̫ҨҚȁTϬхɫ̫нѐʄƄωϬϻ̻̫ҘЙ ě*À ʠʌΠ¢˜Ѝ*À̫ʬľ˜Ѝüɮn̛ User.new Ĵū µƶ žПή‚ġ ǝ˜Ѝ³Ϭ ȏɕȰū‘ɕȰƯ 14ž̷Ĉ Email ĵĸ̫ͩ ˜ЍŠR̀ 6.15 ȁ͈ R̀ 6.15 țΘ̷Ĉ Email ĵĸ̫˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com") end . . . describe "when email address is already taken" do before do user_with_same_email = @user.dup user_with_same_email.save end it { should_not be_valid } end end ǻUn̛ @user.dup ɟ˓µƶ ě @user Email ĵĸ ʠ̛̫ȀžП˼Ċū‡ї̛Ȁĭ$ɕȰƯ ̫ @user ƝΒá̛5ї Email ĵĸȁTιǺÉū‘ɣ˓nj» ć˓̛̫ȀЁDŽ R̀ 6.16 ̫R̀þTϽR̀ 6.15 ̫˜Ѝѫѐ R̀ 6.16 ӎЈ Email ĵĸ̫ġ ǝ app/models/user.rb class User < ActiveRecord::Base . . 14. ŠʄωKΑ ȁЗ̫їѾƊϬ̛»˜ЍɕȰƯ db/test.sqlite3 5 199 . validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: true end їіϡ υʌЗ Email ĵĸɮȧ˽ׯœƄ¢ʌŌ̫̕0ƊЗ foo@bar.com ě FOO@BAR.COM Ǽ FoO@BAr.coM ɮͪɐ̫ȁTӎЈɩ0Ϭάϛї͑ǧ¥15R̀ 6.17 ɮ҂žї͑ҕӄ̫˜ЍR̀ R̀ 6.17 țΘ̷Ĉ Email ĵĸ̫˜ЍׯœƄ¢ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com") end . . . describe "when email address is already taken" do before do user_with_same_email = @user.dup user_with_same_email.email = @user.email.upcase user_with_same_email.save end it { should_not be_valid } end end ҷ̫R̀ĴŪͨ"Л̛5 upcase ɟ˓ì˽ 4.3.2 ωї˜ЍěÀҷž̷Ĉ Email ĵĸ̫˜ЍͶb üɮȏ Email ĵĸтȮǺ’Ѹœ¢Ūʾ̫DžƻŠʔϳnjŕȗПѶƊĴȸ¼ÿ ųɈ Ď $ rails console --sandbox >> user = User.create(name: "Example User", email: "user@example.com") >> user.email.upcase => "USER@EXAMPLE.COM" >> user_with_same_email = user.dup >> user_with_same_email.email = user.email.upcase 15. ʣ̫ЗEmail ĵĸüɽŁĉѸ¯ɮׯœƄ¢̫foo@bar.com ě Foo@bar.com ˜ųɮĈ̫ĵĸcĴųҠn ̛ ÚºqЯїϰ³about.com ̷–̫ɘͥЗѱ“ׯœƄ¢̫ Email ĵĸ_ƢʌNjŐӖ˻ɫ=Ȯn̛0¹ `ɆȁTϬˇъ‘ʵ͆ĵœƄ¢ɮNjDzϠ̫©+ˎɽ Email ɿËȼpĢǼ ISP ǁ¼Ϭˇn̛ׯœƄ¢̫ Email ĵĸ0 _ȼ͈ɋVG̫œƄ¢Ҍ5oŠϬ’Ѹœ¢”dzНЙέ Riley Moses Ȧʵїҕӄ 200 ͩ 6 ͥ ̛Ȁʬľ >> user_with_same_email.valid? => true ̓Ĵ user_with_same_email.valid? ̫ѕĬ~ɮ trueĭ$ġ ǝӎЈіɮׯœƄ¢̫ǻUơʀnj»̫ Δʔɮ falseƬş uniqueness þTȦŲ :case_sensitive ѥһʵşþTϵ¤їҕӄŠR̀ 6.18 ȁ ͈ R̀ 6.18 ӎЈ Email ĵĸ̫ġ ǝׯœƄ¢ app/models/user.rb class User < ActiveRecord::Base . . . validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } end ˕DZǻU̶ȷȏ true ȮǺ5 case_sensitive: falseRails _οÌȦŲ :uniqueness ̫~$ trueπ ʶư̛͘ƮϝіɽзcŃʄþTwЈ Email ĵĸ̫ġ ǝ5ȁɽ̫˜ЍѹþTѫѐ5 iªźľû Ŋ ̓Ĵіɽ ƄҕӄĴʶϦǏ̫ȼѻl ġ ǝӎЈɣ˓̻ʵwЈġ ǝ _ĎĠѾ¬5ҕӄĖ ҷǻʌϵѽ  1. Alice ̛ alice@wonderland.com ˕ž 2. Alice ƄǏȧ5ʭȼBȧ҄ћΛòѡ5ʭИˇ 3. ˼ĊƊ_ò̚ҷ̫8ǧ Иˇ 1 Ĵū ɞƶ5 ̛ȀžПѫѐӎЈ Иˇ 2 0 ʠИˇ 1 µƶ ̛̫Ȁū‘5ɕȰƯИˇ 2 µƶ̛̫Ȁ0ū‘5ɕȰƯ 4. ΔʔɮƌͰɽġ ǝӎЈɕȰƯ іɮɽʋ̛ȀЁDŽ̫ Email ĵĸɮ ʠ̫ ̷xǻҷї͑ҭTΦx̫ѐ͘ɮþι_ò̫̚üϬɽ Ų̫ЇҕҀĴXh Rails Τͤ ѹþιò̚Ƭş ϵ¤̫È˓NjŹɫų̓üҲĴɕȰƯƏ0Êġ ǝҤ¼ǻUϬ‚̫ɮĴɕȰƯ $ email ²ƶ͢΂Ƽ˼ Ċ$΂ƼÊġ ǝҤ¼ $ email ²ƶ͢΂ƼƊϬɌõɕȰƯʬľĴ Rails þTѫѐю͗ų̓ìϮ 6.1.1 ωĴ 6.1.1 ω ǻU̺ »̚Ǻ User ʬľɩ_ο̵ƶ ю͗ɘVìϮR̀ 6.2̓ĴǻUɮϬɌõƝΒūĴ̫ʬľΔʐѶ(n ̛ migration ĚS̶ȷµƶю͗ɘVƊþT5 $ rails generate migration add_index_to_users_email ě User ʬľ̫ю͗ ʠų̓ Email ġ ǝ̫ю͗Ɉkˎɽ8Ų)̫ʬʎþ̛ȁTǻUϬȂÌȏR̀ 6.19 ̫Ź¢‘ю͗ɘV16 201 R̀ 6.19 ͆w Email ġ ǝ̫ю͗ɘV db/migrate/[timestamp]_add_index_to_users_email.rb class AddIndexToUsersEmail < ActiveRecord::Migration def change add_index :users, :email, unique: true end end ѝR̀Л̛5 Rails ̫ add_index ɟ˓$ users ϥ̫ email ²ƶ͢΂Ƽ΂ƼʄсƫιwЈġ ǝ ȁTіϬȦŲ unique: true ˼ĊȆϡɕȰƯю͗Ɉk $ bundle exec rake db:migrate ŠʔŗХ̫ЏƊѠ¬ȁɽȄƷ̫ȸ¼ÿˌ̰_ЏїA_Џþι_ҊŲɕȰƯțΘјϡю͗ɈkŠʔl ǯ̺ ɈkȆϡĊ̫ɐʔИȄƷ db/schema.rb ɘV_ò̓Ő5 ϡ add_index "users", ["email"], name: "index_users_on_email", unique: true $5wЈ Email ĵĸ̫ġ ǝіϬ‚AyɌ ū‘ɕȰƯ*Àȏ Email ĵĸтȮǺ’Ƅ¢Ūʾ̫Džƻĭ$ɮ ȁɽɕȰƯѢѺĩ̫΂ƼѹɮׯœƄ¢̫17 $ʶǻUϬn̛ĬЛ®ɕcallbackĴ Active Record žП̚ Ěėʁ̫̆Ųɩ¾Л̛ìҘ Rails API –:ĬЛ®ɕ̫ɘʦʄo ǻUϬn̛̫ĬЛ®ɕɮ before_saveĴ̛Ȁū‘ɕȰƯ*Àǁϡȏ Email ĵĸтȮǺ’Ƅ¢ŪʾDžƻŠR̀ 6.20 ȁ͈ R̀ 6.20 ȏ Email ĵĸтȮǺ’Ƅ¢Džƻ͆wġ ǝ app/models/user.rb class User < ActiveRecord::Base before_save { self.email = email.downcase } . . . end ĴR̀ 6.20 before_save Ċкɽ ĻĻ ̫R̀Л̛5Ūͨ"̫ downcase ɟ˓ơ̑Ȁ̫ Email ĵĸ тȮǺƄ¢ŪʾDžƻїAR̀ɽAˤƴʶɩlüҲ̷xїAR̀þTэ»̴̫Ɗϡ5Šʔlɽȁǘ̥þT ȏR̀ 6.16 ̫ġ ǝӎЈR̀˕ѽȳµƶ© Email ĵĸ ʠ̛̫Ȁ̺ ū‡ɩnj»̫ҌЕxǠ8.2.1 ω і_̛»їȎƚ»ɩ_n̛ȹϐ̫“ɟ˓Ƽ̛”·ŲΠ¢҂žR̀ 6.20 ̫˜Ѝ_̢kΌ1ìϮ 6.5 ω πʶҷ Alice ѯ»̫ҕӄƊϵ¤5ɕȰƯ_ū‡Иˇ 1 µƶ̛̫Ȁ_ū‡Иˇ 2 µƶ̛̫Ȁĭ$Ůњ ñ5ġ ǝҤ¼Ĵ Rails ̫ɥǒ _ɯ͈ ҌЕѐɣœ͇˜ųǻUþTȬϓȒ¬̫ ActiveRecord::StatementInvalid ƸƤѐʄɓ͘_ˠîƸƤŌ̕$ email ²ƶ͢΂ƼĈɩ0ϵ ¤5 6.1.4 ω ȼ»̫ find_by_email ̫ɐ̐ҕӄìҘɡ˕ 6.2 16. ǃ˼ǻUþT̶ȷΠщR̀ 6.2ѐҲϬĬˮŸю͗Ĭʌїɮ Rails ̫ӈʣʵ̫͆‚˓ɮʿʭyɌɕȰƯΔʐ ѹϬn̛ю͗ 17. ǻĴʄĵ̫ SQLite Tî Heroku ̫ PostgreSQL ‚ѐųӎЈɪї(‚˜ųɮǐҽ̫ 202 ͩ 6 ͥ ̛Ȁʬľ Íå 6.2Ç·œĒ¢ µƶɕȰƯ²ɩϬάϛɮč_̛ї²јϡʙБoŠR̀ 6.2 ̫ю͗µƶ5 email ²ͩ 7 ͥ ų ̛̫̓Ą̏DŽÉι_ѫѐȼB̫ Email ĵĸʙБžư̛̫ȀЁDŽȧ˽̓ɽ̫ɕȰʬľn̛ Email ĵĸʙ Ơ̏Ȁ̫ġ ɟƻɮѰèɕȰƯ ȁɽ̛̫ȀЁDŽžˀȼB̫ Email ĵĸěЁDŽ ̫ email ²̺̺ɮč ρĴɕȰƯ̫ʅД їý‚“’ϥȈȻfull-table scan”ž ɽỨȀ̫ΤͤήϷїþɮ V хʍ̫8 $ email ²ƶ͢΂Ƽ³þTϵ¤їҕӄǻUþTƃɕȰƯ΂ƼˀȝǺ2͵̫΂ƼŠʔϬĴ ʄ2 Ȍ ¬ʗŪͨ"oŠ "foobar"¬̫̓ȁɽdΦǻUҲϬΪ̺2 ̫ʿ ҹcɮŠʔɽ΂Ƽ̫ЏüҲ Ĵ΂Ƽ Ȍ» "foobar" ʋ̴Ɗι̺»ȁɽÓď "foobar" ̫ҹ̀ɕȰƯ΂ƼŃʄ0ɮї͑ê̕ 6.3 L „9‰ÿ ʄωǻUϬʑ̛ȀȁҲ̫ɼĊ ƤϰƓǝ ů’ź̛̀ʌӎЈ̛Ȁ̫сYų̫̓ɟƻɮ̛ȀЁ̽οƜ̫ ź̀ήĴɕȰƯ ū‡̽ÊźĊ̫ź͙̀ĊǻUі_ʑŃ:ź̛̫̀ȀсYӎЈʆ¼ͩ 8 ͥ_¹̛їʆ ¼ų̛̓Ą̏DŽÉι ӎЈ̛ȀсY̫ɟ˓ɮϓớȀȼB̫ź̀јϡÊźŸěɕȰƯ ū‡̫Êźź̀žˀŠʔ9έ ρ̛ ȀȼB̫Ɗɮʵ̫͆ź̛̀Ȁ̫сY0ƊӎЈ5ǻUϬžˀ̫ɮÊźĊ̫ź̀ήɮêţ̫ź̀ɘʄȁT ӎЈ̛ȀсYɩ̛ĴɕȰƯ ū‡̛Ȁ̫ź̀їʠþTϰѵ Njœ̫ů’ҪǤ ů’ź̀ʆ¼Ńʄɮ̜ Rails Þ̫̌ɟ˓ has_secure_password ų̫̓ο Rails 3.1 Ʒţn̛ĭ $ĊΛ̫ŹѹɮŃ:їɟ˓̫ȁTNjҭǍƮ˨ј̫ЂϵM 6.3.2 ωƷţǻƶϿƌɨ̫ʑ has_secure_password ɟ˓˼ĊʿΠ¢ ˜ЍƊ˕ѽȳїɟ˓їʠȃιʵ̫͆n̛ TDDϱӃLjLj ιɹş̫ϥ̓ ǍƮ˨ј̫Ʒòѐ͘ȁT$5ιɹş̫̕ϵї Ļɽ—ж̫ЙέþTάϛϯ̺ʄɓ̫͘Ѻŝ ϱӃ 6.3.1 L‰‰ÿ ǻUϬž User ɕȰΔʐ‚AɌÌċ users ϥ ʑ password_digest ²Šij 6.5 ȁ͈digest їЋ ɮÊźĝơ®ɕ ̫ ʅД*ȁTϬn̛ password_digest Ěĉї²ɮĭ$ 6.3.4 ωų̫̓Éι_̛» ї²Ѣǃ̫ÊźĊåtɍ­έІ˓ϓó5ɕȰƯȡС0ɣ˓ӘȳΤͤ ij 6.5 ʑ password_digest ƓǝĊ̫ User ʬľ 203 ǻUϬn̴̛Àɼј̫ĝơ®ɕ bcrypt žź̀јϡþѤ̫Êźnj»ź̫̀ĝơ~ŠʔϬĴ͘Ʈ n̛ bcryptҲϬȏ bcrypt-ruby ї gem ʑ GemfileŠR̀ 6.21 ȁ͈ R̀ 6.21 ȏ bcrypt-ruby ʑ Gemfile source 'https://rubygems.org' ruby '2.0.0' gem 'rails', '4.0.0' gem 'bootstrap-sass', '2.3.2.0' gem 'bcrypt-ruby', '3.0.1' . . . ˼Ċѓϡ bundle install ůϪ $ bundle install ɤ˼ǻUϰ±̫ users ϥ ɽ ²ɮ password_digestѶ(̛ȀžПƊưВþTĞư password_digest ɟ ˓ȧ˽їǜмǻUƊþTΠ¢¬ŠR̀ 6.22 ȁ͈̫˜Ѝ R̀ 6.22 ͆w users ϥ ɽ password_digest ² spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com") end subject { @user } it { should respond_to(:name) } it { should respond_to(:email) } it { should respond_to(:password_digest) } . . . end $5Ͻ˜ЍѫѐӊϬ̚Ǻ ćѢ̫ю͗ɘV˦Ê password_digest ² $ rails generate migration add_password_digest_to_users password_digest:string 204 ͩ 6 ͥ ̛Ȁʬľ ѝĚS̫ͩ ìɕɮю̫͗ĉŪͩ9ìɕȦɪϬ˦ʲ̫ĉŪěɕȰͶľþTěR̀ 6.1 ̚Ǻ users ϥ̫R̀žˀ ю̫͗ĉŪþTҩtгc υ_T _to_users ΔƍRails _οÌ̚Ǻ ċ users ϥ ňʲ̫ю͗ǻUіȼp5ͩ9ìɕRails Ɗnj»5зŒ̫xǠ_$ǻU̚Ǻɗю͗ɘV ŠR̀ 6.23 ȁ͈ R̀ 6.23 ċ users ϥ ˦Ê password_digest ²̫ю͗ db/migrate/[ts]_add_password_digest_to_users.rb class AddPasswordDigestToUsers < ActiveRecord::Migration def change add_column :users, :password_digest, :string end end ѝR̀ Л̛ add_column ɟ˓ċ users ϥ˦Ê password_digest ² ĴƷòɕȰƯ Ȇϡю͗ɈkŸ¦ōş˜ЍɕȰƯR̀ 6.22 ̫˜ЍƊþTѫѐ5 $ bundle exec rake db:migrate $ bundle exec rake test:prepare $ bundle exec rspec spec/ 6.3.2 ‰ÿh‰ÿĀĸ Šij 6.1 ̫ʐǜijȁ͈ǻUơʀ̛Ȁјϡź̀͆ϻїĴΤΗ ɮNjɱѰ̫‚˓þT§ƄЕъ‘Ƣʌ̫ӈ ҧϝ˼Ĵȸ¼ĩƏþTų̓їǯ˓ѐĴʬľƏų̓ɹşActive Record þT͆wź̀͆ϻɣ ŗ$ ʶǻUϬȏ password ě password_confirmation ²Ê‘ User ʬľĴЁDŽū‘ɕȰƯ*Àˀчї² ̫~ɮč ʠě*ÀϮѐ̫Ɠǝ ʠpassword ɮϜȝ̫Ɠǝüɮ#ɩūĴ:ū ή_ū‘ɕȰƯ  ǻUΠ¢ʨʙɮčþTĞư password ě password_confirmation ɟ˓̫˜ЍŠR̀ 6.24 ȁ͈ R̀ 6.24 ˜Ѝ password ě password_confirmation Ɠǝ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end subject { @user } 205 it { should respond_to(:name) } it { should respond_to(:email) } it { should respond_to(:password_digest) } it { should respond_to(:password) } it { should respond_to(:password_confirmation) } it { should be_valid } . . . end ˕DZǻUĴ User.new ̫¶ţÔìɕ Hash ʑ5 password ě password_confirmation before do @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end ǻUǃ˼ǯϽ̛Ȁъ‘̩̫͝ź̀Ѷ(ŸΠ¢ ӎЈź̀ūĴǝ̫˜Ѝ describe "when password is not present" do before do @user = User.new(name: "Example User", email: "user@example.com", password: " ", password_confirmation: " ") end it { should_not be_valid } end ĭ$͙Ċ_˜Ѝź̀ ρ̫ǧDžȁTūĴǝӎЈƊȏź̀ěź̀͆ϻһѹІ$5͝ʣŪͨ" ǻUіϬ͆wź̀ěź̀͆ϻ̫~ɮ̷Ĉ̫ї͑ǧ¥ it { should be_valid } ƝΒϭ̱5Ѷ(ŸΠ¢҂ ž9έĈɩ̫˜ЍƊþT5 describe "when password doesn't match confirmation" do before { @user.password_confirmation = "mismatch" } it { should_not be_valid } end ȏѝR̀ɎĴ гƊɮR̀ 6.25 ̫ŗХ˜Ѝ5 R̀ 6.25 ž password ě password_confirmation ̫˜Ѝ spec/models/user_spec.rb 206 ͩ 6 ͥ ̛Ȁʬľ require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end subject { @user } it { should respond_to(:name) } it { should respond_to(:email) } it { should respond_to(:password_digest) } it { should respond_to(:password) } it { should respond_to(:password_confirmation) } it { should be_valid } . . . describe "when password is not present" do before do @user = User.new(name: "Example User", email: "user@example.com", password: " ", password_confirmation: " ") end it { should_not be_valid } end describe "when password doesn't match confirmation" do before { @user.password_confirmation = "mismatch" } it { should_not be_valid } end end ǻUüҲ˦Ê ϡR̀ƊþTϽR̀ 6.25 ̫˜ЍѫѐŠR̀ 6.26 ȁ͈ R̀ 6.26 Ͻź̀˜Ѝѫѐ app/models/user.rb class User < ActiveRecord::Base . . . has_secure_password end 207 has_secure_password ї ϡR̀ɮNjǁœ̫þTϽȁɽ҂žź̫̀˜Ѝѹѫѐήk̛і̾Šʶc ɮїϡR̫̀k̛ŕѐǁœ̙πĊҷ̫˜ЍʂѯΆƊõΝ5ȁTĴΚΛ*ÀǻƶϿȏїϡ˕ѽȳŠR̀ 6.27 ȁ͈ R̀ 6.27 $5оϡ TDD˕ѽȳ has_secure_password app/models/user.rb class User < ActiveRecord::Base . . . # has_secure_password end 6.3.3 ö®ō)źľ ų̓ź̀ʆ¼̫ɼĊ ʷɮȌ» ͑ɟ˓n̛ Email ĵĸěź̀óĬ̛ȀžПїɟ˓Njο˼̫þT¯Ǻ ʷӊѫѐ Email ĵĸȌ»̛ȀЁDŽ ˼ĊŸ̛ź̀јϡсYӎЈҦ5ɼĊ ˜Ѝʄωȁɽ˜Ѝѹɮѫ ѐ has_secure_password ų̫̓ȁT$5Ͻ˜ЍѫѐǐҽϵҦR̀ 6.27 ̫˕ѽϡ ͩ ʷNjͮÞŠ 6.1.4 ω KΑѐ̫ǻUþTЛ̛ find_by ɟ˓ѫѐ Email ĵĸʙƠ̏ȀЁDŽ user = User.find_by(email: email) ȷʌ̫ͩ9ʷþTn̛ authenticate ɟ˓ӎЈ̛Ȁ̫ź̀Ĵͩ 8 ͥ _n̛Ͷbҷ̫R̀ϓóǃĄ̀ DŽ̛̫Ȁ current_user = user.authenticate(password) ŠʔȼB̫ź̀ě̛Ȁ̫ź̀ ρѝR̀Ɗ_ѕĬ ̛ȀžПč³ѕĬ false ě*À ʠǻUþTn̛ RSpec ˜ЍǐҽϬŲ)ɽ authenticate ɟ˓ї˜ЍˀÀҷϮѐ̫Ϭҭ AǻU¯ʼ ʌ̺Šʔl´ȷ϶ RSpecþιϬŐЙ©Ѱʄω̫Źӊ̛ȀžПưВιŒĞư authenticate ɟ˓ it { should respond_to(:authenticate) } ˼Ċ˜Ѝź̀ɮčʵ͆ describe "return value of authenticate method" do before { @user.save } let(:found_user) { User.find_by(email: @user.email) } describe "with valid password" do it { should eq found_user.authenticate(@user.password) } end 208 ͩ 6 ͥ ̛Ȁʬľ describe "with invalid password" do let(:user_for_invalid_password) { found_user.authenticate("invalid") } it { should_not eq user_for_invalid_password } specify { expect(user_for_invalid_password).to be_false } end end before Ļ ̫R̀ơ̑Ȁū‘ɕȰƯ˼ĊĴ let Ļ Л̛ find_by ɟ˓ó¬̛Ȁ let(:found_user) { User.find_by(email: @user.email) } ĴÀ©̫ͥΌ1ӄ ̛ѐNjŐʭ let 5cїɮͩ ʭĴʵɘ ¬̓ɡ˕ 6.3ч$ˤ‘̫KΑ5 let ɟ˓ȷ ʌ̫ describe Ļ˜Ѝ5 @user ě found_user ɮč$Ĉ ̛Ȁ˜ЍR̀ n̛ eq ˜ЍžПɮč̷Ĉ _Л̛ == ˜Ѝɮč̷ĈìϮ 4.3.1 ω˕DZҷ̫˜Ѝ describe "with invalid password" do let(:user_for_invalid_password) { found_user.authenticate("invalid") } it { should_not eq user_for_invalid_password } specify { expect(user_for_invalid_password).to be_false } end Ÿʭ̛»5 let ɟ˓і̛»5 specify ɟ˓specify ɮ it ɟ˓̫ºĉŠʔlϳnjʗĵɟ̛ it Йгʌ ǞǞ̫ƊþTƠ̇ specifyʄo “it should not equal wrong user”ЙгʌNjҼѐ“user: user with invalid password should be false”ɽ˸΄аƠ̇“specify: user with invalid password should be false”dzϳƊşA Íå 6.3let Ìä ǻUþTn̛ RSpec ȼp̫ let ɟ˓tȱ̫Ĵ˜Ѝ Ų)ƎѸõҀlet ɟ˓̫ú˓̺гʌɽ˸Ǟѐě õҀЭ~Дú̫k̛ɮ ʠ̫let ɟ˓̫ìɕɮ  SymbolĊҷþTк̽ ĻĻ R̫̀ѕĬ~_Э Ζĉ$ Symbol Rϥ̫ƎѸõҀ0ƊɮЗ let(:found_user) { User.find_by(email: @user.email) } Ų)5 ĉ$ found_user ̫õҀ˜~ͪ: find_by ̫ѕĬ~Ĵї˜Ѝ̛o̫Xh  before Ǽ it Ļ ѹþTn̛їõҀn̛ let ɟ˓Ų)õҀ̫ şŌɮŮþTЁfmemoizeõҀ̫~ memoize ɮϡʅДɮ“memorize”̫ЕȢ¢žҷ̫R̀ήϷĭ$ let ̫ōǓÉι found_user ̫~_ϧЁfĭʶͰЛ̛Őƅʭ User ʬľ˜Ѝfind_by ɟ˓ü_ѓϡ ʭ ɼĊů’гϮǻUіϬΠ¢ ź̀ґƴ˜Ѝœ: 6 Ūͨȃιѫѐ 209 describe "with a password that's too short" do before { @user.password = @user.password_confirmation = "a" * 5 } it { should be_invalid } end ȏҷ̫R̀ɎĴ гĊŠR̀ 6.28 ȁ͈ R̀ 6.28 ž authenticate ɟ˓̫˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end subject { @user } . . . it { should respond_to(:authenticate) } . . . describe "with a password that's too short" do before { @user.password = @user.password_confirmation = "a" * 5 } it { should be_invalid } end describe "return value of authenticate method" do before { @user.save } let(:found_user) { User.find_by(email: @user.email) } describe "with valid password" do it { should eq found_user.authenticate(@user.password) } end describe "with invalid password" do let(:user_for_invalid_password) { found_user.authenticate("invalid") } it { should_not eq user_for_invalid_password } specify { expect(user_for_invalid_password).to be_false } end 210 ͩ 6 ͥ ̛Ȁʬľ end end Šɡ˕ 6.3 KΑ̫let ɟ˓_ЁfõҀ̫~ȁTƖŝ ̫ͩ  describe Ļѫѐ let ɟ˓ȏ find_by ̫ ΔʔЭ~Ζ found_user *ĊĴĊΛ̫ describe Ļ ƊɣҲŸʭʙБɕȰƯ5 6.3.4 ö®û„9‰ÿ Ĵчɧ̂ʄ̫ Rails ˦Ê ů’̫ź̀ɮNjӖ˻0NjЫɩ̫8ʄ2̫ͩ ̂҂ž Rails 3.0 ƊMұгƷ ò5 ̛ȀсYӎЈ΀Ι˾̛̾ȀсYӎЈ΀Ι̫ƷòέےˎǐϬĴʶ˞ЫɩҖȁTĴ Rails ̫ɼɞ̂ ƝΒүǺ5̛ȀсYӎЈÉιĭʶǻUüҲϬ©ϡR̀ƊþT$̛Ȁ˦Ê ů’̫ź̀іþTϽÀ©Ƅω ̫˜Ѝѫѐ ӊǻUϬ$ź̀˦Ê ґƴӎЈn̛ěR̀ 6.12 ̛ѐ̫ :maximum Ͷb̫ :minimum validates :password, length: { minimum: 6 } ź̀ěź̀͆ϻ̫ūĴǝӎЈѹĴ has_secure_password ɟ˓ ų̓5 ˼ĊǻUϬ˦Ê password ě password_confirmation Ɠǝ9έѹϬņ¢ AŹҵ͝ʣήϬ̷ ͪ іϬŲ) authenticate ɟ˓žˀÊźĊ̫ź̀ě password_digest ɮč ρӎЈ̛Ȁ̫сYїA ʷӏʄʌNjӖ˻ѐĴɼɞ̫̂ Rails ƝΒүǺş5üҲЛ̛ ɟ˓ƊþT5їɟ˓ɮ has_secure_password has_secure_password üϬɕȰƯ ɽ password_digest ²ĴʬľɘV ʑ has_secure_password ɟ˓ĊƊιӎЈ̛ȀсY 5 Šʔlϳnj has_secure_password ɟ˓ŕѐ͋ŚŢҘЙ  secure_password.rb ɘV ̫R̀Ѿ ҷɽNjŐ˕ѽR̀ʄс0ҭ̕ϵїʼR̀ ɽї(©ϡ validates_confirmation_of :password, if: lambda { |m| m.password.present? } їϡR̀_ο̵ƶ password_confirmation ƓǝRails API ɽЗɪїʼR̀іɽ҂ž password_digest Ɠǝ̫ɕȰӎЈ ȏT̫R̀ɎĴ гƊnj»5ŠR̀ 6.29 ȁ͈̫ User ʬľĈɩ0ų̓5ů’̫ź̀ʆ¼ R̀ 6.30 ɼΐų̫̓ů’̫ź̀ʆ¼ app/models/user.rb class User < ActiveRecord::Base before_save { self.email = email.downcase } 211 validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } has_secure_password validates :password, length: { minimum: 6 } end ̓ĴlþT̺ ˜ЍɮčþTѫѐ5 $ bundle exec rspec spec/ 6.3.5 Ežö® πʶŃʄ̫ User ʬľƝΒʖʐş5ȷʌǻUϬĴɕȰƯ ū‘ ̛ȀЁDŽ$ 7.1 ωƷờ̫ȀЬəɯ͈ ҹҷ‚¦ōĈɩ0þT̺ À©ωȁ‚Ƙk̫ųҠɐʔ˜ЍѫѐƫDZĘ̽Ƙk‚Ű5ŠʔƷòɕȰƯ ɽ ʋ̛ȀЁDŽ̫ЏǼЄιΖǻUƢʌ ˸ǺƊdz ĭ$̓ĴіιĴΤҹ ˕žͩ 7 ͥ_ų̓ǻUϬĴȸ¼ÿ Ȃ̵ƶɞ̛Ȁě 6.1.3 ω ʠʄωn ̛̫ɮˌ̰ʬƻ̫ȸ¼ÿĭ$ǻU̻̫ϬĴɕȰƯ wū ʋЁDŽ $ rails console >> User.create(name: "Michael Hartl", email: "mhartl@example.com", ?> password: "foobar", password_confirmation: "foobar") => # Ĵ SQLite ɕȰƯ˝ϲĩ ȄƷƷòɕȰƯdb/development.sqlite3_ò̓ѝĚSȆϡĊū‘̫ЁDŽ Šij 6.6Ć²žư5ij 6.5 ɕȰʬľ̷ư̫Ɠǝ 212 ͩ 6 ͥ ̛Ȁʬľ ij 6.6 SQLite ɕȰƯdb/development.sqlite3 ̫ ʋЁDŽ ŸĬ»ȸ¼ÿ Йó password_digest Ɠǝ̫~̺ R̀ 6.29 has_secure_password ɟ˓̫k ̛ >> user = User.find_by(email: "mhartl@example.com") >> user.password_digest => "$2a$10$kn4cQDJTzV76ZgDxOWk6Je9A0Ttn5sKNaGTEmT0jU7.ncBJ/60gHq" їɮ¶ţƠ̂Ȁɩȼp̫êţź̀"foobar"žư̫ÊźDžƻҷŸʌӎЈ  authenticate ɟ˓ɮč þTʵƤn̛ȼpʵ̫͆ź̀Ÿȼpʵ̫͆ź̀ΔʔŠ >> user.authenticate("invalid") => false >> user.authenticate("foobar") => # ŠR̀ 6.28 ̫˜ЍҲˇŠʔź̀ʵ͆authenticate ɟ˓_ѕĬ false Šʔź̀ʵ͆³_ѕĬžư ̛̫ȀžП 213 6.4 ŒĘ ʄͥMұƷţƶ͢5 ѓkφş̫ User ʬľÓď nameemail Tî©ź̷̀–̫ƓǝѫѐɕȰӎЈž Ɠǝ̫ó~‚5ҤŲήƝΒþTn̛ź̀ž̛ȀјϡсYӎЈ5Ĵчɧ̂ʄ̫ Rails ų̓їAÉιҲ ϬΠ¢œҀ̫R̀ѐĴɼɞ̂ n̛ǁœ̫ validates ě has_secure_password ɟ˓üҲ©ϡR̀ ƊþTʐƶŰɗ̫ User ʬľ5 Ĵȷʌ̫ͩ 7 ͥ ǻU_µƶ ˕žϥÞ̛ʌɞƶ̛Ȁі_µƶ ҹҷ̛ʌɯ̛͈Ȁ̫xǠͩ 8 ͥ³ _n̛ 6.3 ωų̫̓сYӎЈʆ¼Ͻ̛ȀþT̨DŽΤͤ Šʔln̛ Gitή ̶ѹˎ‚ȼB̫Џ̓ĴɼşȼB ʄͥȁ‚̫ɌÌ $ git add . $ git commit -m "Make a basic User model (including secure passwords)" ˼Ċćƫ»%¯Ɋ $ git checkout master $ git merge modeling-users 6.5 Ė 1. $R̀ 6.20 ȏ Email ĵĸтȮǺƄ¢ŪʾDžƻ̫ÉιΠ¢ ˜Ѝ˜ЍR̀þTìάR̀ 6.30їʼ ˜Ѝn̛ reload ɟ˓MɕȰƯ ѿɞÊцɕȰ n̛ eq ɟ˓˜Ѝ̷ͪȏR̀ 6.20 ̫ before_save ϡ˕ѽȳ̺ R̀ 6.30 ̫˜ЍɮčþTѫѐ 2. ȏR̀ 6.20 before_save ϡɌǺR̀ 6.31 ̫Džƻѓϡ˜Ѝ̺ їʠɌ¢ɮčþϡ 3. ǻUĴ 6.2.4 ω ЗѐR̀ 6.14 ̫ Email ʵ³ϥэƻιÖѺ¬̓ћΛ˸Ă̫ć˓ Email ĵĸoŠ “foo@bar..com”ȏїĵĸ˦Ê»R̀ 6.13 ̫ć˓ĵĸ²ϥ Ͻ˜ЍŗХ˼Ċn̛R̀ 6.32 ч Ŏʇ̫ʵ³ϥэƻϽ˜Ѝѫѐ 4. ѫЙ Rails API –: ActiveRecord::Base ̫Ź5ϵ їͶ̫k̛ 5. ΎЙ Rails API –: validates ɟ˓̫Źŭ1їɟ˓˜P̛̫˓ěìɕ 6. ϊ˸ɩҖ˾ǣ  Rubular R̀ 6.29 žR̀ 6.20 Email õƄ¢̫˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do . . 214 ͩ 6 ͥ ̛Ȁʬľ . describe "email address with mixed case" do let(:mixed_case_email) { "Foo@ExAMPle.CoM" } it "should be saved as all lower-case" do @user.email = mixed_case_email @user.save expect(@user.reload.email).to eq mixed_case_email.downcase end end . . . end R̀ 6.30 before_save ĬЛ®ɕ̫û ͑¢˓ app/models/user.rb class User < ActiveRecord::Base has_secure_password before_save { email.downcase! } . . . end R̀ 6.31 ŠЄ Email ĵĸ ¬̓ћΛ˸Ă̫ʵ³ϥэƻ app/models/user.rb class User < ActiveRecord::Base . . . VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } . . . end 215 ĉ 7 ć ö®å> User ʬľþTʵƤn̛5ȷʌϬų̫̓ÉιœŐɕΤͤѹ͎Ʒ ̛Ȁ˕žĴ 7.2 ωǻU_µƶ ϥÞ ȼB̛Ȁ˕žɩņ¢̫xǠ˼ĊĴ 7.4 ω n̛ȼB̫ɕȰµƶɞ̛Ȁȏ̷ư̫Ɠǝ~ū‘ɕȰƯ˕žÉι ų̓ĊіϬµƶ ̛ȀЬəҹҷɯ̛͈Ȁ̫GxǠїɮų̓ Users Ьˬ REST ʖʐìϮ 2.2.2 ω̫ͩ ʷě*À ʠƷò̫ѐ͘ ϬΠ¢˜ЍΔć RSpec ě Capybara ¢¬ͮ˖ɽɐ̫үǺ˜Ѝ µƶЬəҹҷ*ÀɕȰƯ Ϭɽ̛ȀЁDŽїɽ˸Ͷb“ɽӕіɮɽϟ”̫ҕӄ Τͤіˎų̓˕žÉι ɕȰƯ ǚ(_ɽ̛ȀЁDŽĖ ˜ųїҕӄĴ 6.3.5 ω ƝΒϵ¤5ǻUĴȸ¼ÿ ċɕȰƯ ū‡5 ̛ ȀЁDŽŠʔlнѐ5Ѷ ὠĴвǕLjĬΪŰǺ̷ư̫Ɉk Šʔl ̶ļȥn̛̂ʄȸ¼΀ἸĴϬɞƶ M¯Ɋ5 $ git checkout master $ git checkout -b sign-up 7.1 Ðāö®1« ʄωϬų̛̫̓ȀЬəҹҷɮŰɗҹҷ̫ ƄѸ¯üɯ̛͈Ȁ̫ĉŪě؈ʐǜijŠij 7.1 ȁ͈1 ɼΐŰǺ̫ ̛ȀЬəҹҷ_ɯ̛͈Ȁ̫؈ŃʄxǠě AǎàʐǜijŠij 7.2 ȁ͈2Ĵij 7.2 ǻUͩ ʭ̛»5 “lorem ipsum”ádɘŪїAɘŪηĊ̫ɏ8NjɽDZǜɽ̫͝ЏlþT5ϵ ɗЬəҹҷ_ěɗ͈o ͘Ʈ гĴ ͩ 11 ͥŰǺ 7.1.1 ņŀ1«h Rails òv ʄωϬų̛̫̓ȀЬəҹҷɮͩ ̻ʵDZ)̫ÌǙҹҷϝ˼ϱij̫R̀_ÌǙɌõѐʿ̛ȀЬəҹ ҷɯ͈̫ŹæɮÌǙ̫MɕȰƯ Йó̫˦ÊÌǙҹҷ*Àɼş‚A¦ōƘk̓ĴǻUι‚̫ƊɮĴΤͤ ƞƎ ʑ AЛЍxǠìϮR̀ 7.1R̀ 7.1 n̛ Rails Φ̫ debug ɟ˓ě params õҀ7.1.2 ω_Г ΎKΑĴʿ ҹ ѹɯ͈ AžƷòɽȁƣÍ̫xǠ R̀ 7.1 ȏЛЍxǠʑΤ̫ͤƞƎ app/views/layouts/application.html.erb . . 1. Mockingbird ɊȥȽ‘ӆŏ̫ij́ij 7.1 ̫ij́ɮǻn̛ Adobe Fireworks Ê̫ 2. ij ̫ˏӋêijĴʶ http://www.flickr.com/photos/43803060@N00/24308857/ 216 . <%= render 'layouts/header' %>
<%= yield %> <%= render 'layouts/footer' %> <%= debug(params) if Rails.env.development? %>
ͩ 7 ͥ ̛Ȁ˕ž ij 7.1 ʄωϬų̛̫̓ȀЬəҹҷʐǜij ǻUϬĴͩ 5 ͥ µƶ̫οŲ)ʠƻϥɘV ʑ Aʠƻϰ³ìϮR̀ 7.2ΨÔ їAЛЍxǠ R̀ 7.2 ˦ÊΨÔЛЍxǠ̫ʠƻn̛5  Sass mixin app/assets/stylesheets/custom.css.scss @import "bootstrap"; 217 /* mixins, variables, etc. */ $grayMediumLight: #eaeaea; @mixin box_sizing { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } . . . /* miscellaneous */ .debug_dump { clear: both; float: left; width: 100%; margin-top: 45px; @include box_sizing; } ҷ̫R̛̀»5 Sass ̫ mixin Éιµƶ̫ї mixin ĉ$ box-sizingmixin þTȄÓ ΀²̫ʠƻϰ³ pŐʭn̛ӀŌ̕ĩŌ̕ɩ_ȏ .debug_dump { . . . @include box_sizing; } тȮǺ .debug_dump { . . . -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } Ĵ 7.2.2 ω і_Ÿʭ̛»ї mixinΨÔĊ̫ЛЍxǠŠij 7.3 ȁ͈ 218 ͩ 7 ͥ ̛Ȁ˕ž ij 7.2 ɼΐų̛̫̓ȀЬəҹҷʐǜij ij 7.3 ɯ͈̫ЛЍxǠΖ¬5ǃÀҹҷ̫ AxǠ --controller: static_pages action: home їɮ params õҀ̫ YAML3Džƻě Hash Ͷbɯ͈5ǃÀҹҷ̫ȸ¼ĩĉěÌkĉĴ 7.1.2 ω _KΑ˜P ЛЍxǠ̫DZǜ ǻUǯϽѸΧĊ̫͈o͘Ʈɯ͈їЛЍxǠȁTR̀ 7.1 ̛Š̫R̀‚5Ҥ¼üĴ“Ʒò̒Ň” ɯ ͈ if Rails.env.development? 3. Rails ̫ЛЍxǠɮ YAMLYAML Ain’t Markup Languageʣƻ̫ї͑ʣƻžʆĩěGͶѹNjïş 219 ij 7.3 ɯ͈ɽЛЍxǠ̫͈o͘Ʈӊҹ/ “Ʒò̒Ň”ɮ Rails Ų)̫̒Ň* ГΎKΑìϮɡ˕ 7.14üɽĴ“Ʒò̒Ň” Rails.env.development? ȃ_ѕĬ trueȁTҷ̫ ERb R̀ <%= debug(params) if Rails.env.development? %> _Ĵ“̚C̒Ň”ě“˜Ѝ̒Ň” ȆϡĴ“˜Ѝ̒Ň” ɯ͈ЛЍxǠϝ˼ˎɽĺŌc0ˎH(şŌȁTɼ şüĴ“Ʒò̒Ň” ɯ͈ Íå 7.1Rails ûòv Rails Ų)5̒Ň¯ºɮ“̚C̒Ň”“Ʒò̒Ň”ě“˜Ѝ̒Ň”Rails ȸ¼ÿәϻn̛̫ɮ“Ʒò̒Ň” $ rails console Loading development environment >> Rails.env => "development" >> Rails.env.development? 4. lіþTοƜŲ)˜P̫̒ŇГΎɟ˓þTì˽ Railscasts ̫Adding an Environment 220 ͩ 7 ͥ ̛Ȁ˕ž => true >> Rails.env.test? => false ŠÀȁ͈Rails žПɽ  env ƓǝƓǝіþTЛ̛Ć̒Ňžư̫ƞƆ~ɟ˓oŠ Rails.env.test?Ĵ“˜Ѝ̒Ň” ̫ѕĬ~ɮ trueήĴ˜P̒Ň ̫ѕĬ~³ɮ false ŠʔҲϬĴ˜P̒Ň n̛ȸ¼ÿoŠĴ“˜Ѝ̒Ň” јϡЛЍüҲȏ̒Ňĉ͖`ѨΖ console Ě Såþ $ rails console test Loading test environment >> Rails.env => "test" >> Rails.env.test? => true Rails ʄĵɿËĩěȸ¼ÿ ʠәϻn̛“Ʒò̒Ň”ѐ0þTĴ˜P̒Ň ѓϡ $ rails server --environment production ŠʔϬĴ“̚C̒Ň” ѓϡư̛͘ƮϬȼp̚C̒ŇɕȰƯĴ“̚C̒Ň” Ȇϡ rake db:migrate Ě SþT̚Ǻ“̚C̒Ň”ȁҲ̫ɕȰƯ $ bundle exec rake db:migrate RAILS_ENV=production ǻò̓Ĵȸ¼ÿɿËĩěю͗ĚS ȦŲ˜P̒Ň̫ɟ˓ ʠїþι_C̚˥ˡȁTǻ̆DZ˲͈5 ĚS̛̫˓ ҼtЗ ȏư̛͘ƮѸΧ» Heroku ĊþTn̛Š̫ĚSј‘љ̫ͦȸ¼ÿ $ heroku run console Ruby console for yourapp.herokuapp.com >> Rails.env => "production" >> Rails.env.production? => true Heroku ɮ̛ʌѸΧΤ̫ͤƩÿο˼_Ĵ“̚C̒Ň” ѓϡư̛͘Ʈ 221 7.1.2 Users ʼnì Ĵͩ 6 ͥʃƍǻUĴɕȰƯ ū‡5 ̛ȀЁDŽĴ 6.3.5 ωʙ̺ѐ̛Ȁ̫ id ɮ 1̓ĴǻUƊʌµƶ  ҹҷɯ͈ї̛Ȁ̫xǠǻU_ѴM Rails n̛̫ REST ʖʐȏɕȰϱ$ЬˬresourceþTµƶɯ ͈ɹɞě·ҦїīɈk¯ºžư5 HTTP ʜ¦ ̫ POSTGETPATCH ě DELETE Иˇɟ˓ìϮɡ˕ 3.3 ȧ˽ REST ·ŲЬˬ υɮ̜ЬˬĉÊġ ʜЉͨϥ͈̫ž User ήϷǻUȏŮ̺‚ ЬˬϋϬʙ̺ id $ 1 ̛̫ȀƊϬċ /users/1 ĵĸòѡ  GET ИˇREST ʖʐϵʑɩ_οÌȏї GET Иˇ¯ò» show Ì kĭʶїѾˎǐϬȦɪ̛ĠÌk Ĵ 2.2.1 ω ɺΒϮѐid $ 1 ̛̫Ȁžư̫ĵĸɮ /users/1̓ĴЇҕїĵĸ̫Џ_ɯ͈ҌЕȼ͈xǠŠij 7.4 ij 7.4 /users/1 ĵĸɯ͈̫ҌЕ ǻUüҲĴм̜ɘV config/routes.rb ˦ÊŠ̫ ϡR̀ƊþTʵƤЇҕ REST ʖʐžư̫ URL ĵĸ 5 resources :users yɌĊ̫м̜ɘVŠR̀ 7.3 ȁ͈ 222 ͩ 7 ͥ ̛Ȁ˕ž R̀ 7.3 Ĵм̜ɘV ˦Ê Users ЬˬІΦ config/routes.rb SampleApp::Application.routes.draw do resources :users root to: 'static_pages#home' match '/signup', to: 'users#new', . . . end via: 'get' lþιò̓5ǻUȏҷїϡĴR̀ 5.33 ¬̫̓R̀·ȳ5 get "users/new" їɮĭ$ resources :users In /users/1 ĵĸþTЇҕ5ήі$͈o͘Ʈ̫ Users Ьˬȼp5ͨć REST ʖʐ̫ ΀²Ìk5Tî̛ʌϓó̷ư URL ĵĸ̫™ĉм̜named routeìϮ 5.3.3 ωɼΐnj»̫ URIÌ kě™ĉм̜̫žư–΀Šϥʣ 7.1 ȁ͈þTěϥʣ 2.2 žˀ ȷʌ̫ͥ_KΑ show *ŏ̫ȁɽÌ kƫɜŰĦȏ Users ȄѭǺےͨć REST ʖʐ̫Ьˬ ϥʣ 7.1 Users Ьˬžư̫м̜ HTTP Иˇ URL Ìk ™ĉм̜ k̛ GET /users index users_path ɯ͈ȁɽ̛Ȁ̫ҹҷ GET /users/1 show user_path(user) ɯ͈ʗ̛Ȁ̫ҹҷ GET /users/new new new_user_path µƶ˕žɞ̛Ȁ̫ҹҷ POST /users create users_path µƶɞ̛Ȁ GET /users/1/edit edit edit_user_path(user) Πщ id $ 1 ̛̫Ȁҹҷ PATCH /users/1 update user_path(user) ɹɞ̛ȀxǠ DELETE /users/1 destroy user_path(user) ·Ҧ̛Ȁ ˦ÊR̀ 7.3 *Ċм̜Ɗ̚ɐ5cɮҹҷіūĴŠij 7.5ҷǻUƊʌ$ҹҷ˦Ê AŹ7.1.4 ω і_˦ÊɹŐ̫Ź ̛ȀЬəҹҷ̫ϱijūɎĴư̛͘Ʈ̆Ų̴̫DŽ å app/views/users/show.html.erbїϱijěοÌ ̚Ǻ̫ new.html.erbìϮR̀ 5.29Ĉ̓ĴūĴϬȂ̵ƶɞƶ show ϱijĊИ¢‘R̀ 7.4 ̫ R̀ 5. їúЏ̫DZǜɮм̜ƝΒІΦş5c̷ư̫ҹҷіɣ˓ʵƤЇҕoŠ/users/1/edit ƝΒɭƂ» Users ȸ¼ĩ̫ edit Ì k5cɮ edit ÌkіūĴȁTЇҕїĵĸƊ_ɯ͈ ҌЕҹҷ 223 ij 7.5 /users/1 ĵĸ̚ɐ5cɮҹҷūĴ R̀ 7.4 ̛ȀЬəҹҷ̫#ɩϱij app/views/users/show.html.erb <%= @user.name %>, <%= @user.email %> Ĵҷ̫R̀ ǻU€І @user õҀɮūĴ̫n̛ ERb R̀ɯ̛͈Ȁ̫ĉŪě Email ĵĸїěɼΐų̫̓ ϱijɽ˸ ʠĴɼΐ̫ϱij _“Ʒɯ̛͈Ȁ̫ Email ĵĸ ǻUϬĴ Users ȸ¼ĩ̫ show Ìk Ų) @user õҀ̛ȀЬəҹҷȃιʵƤ˪ʘlþι̎»5ǻUϬĴ User ʬľЛ̛ find ɟ˓MɕȰƯ ó¬̛ȀЁDŽŠR̀ 7.5 ȁ͈ R̀ 7.5 ďɽ show Ìk̫ Users ȸ¼ĩ app/controllers/users_controller.rb class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new end end 224 ͩ 7 ͥ ̛Ȁ˕ž Ĵҷ̫R̀ ǻUn̛ params ϓớȀ̫ idǃǻUċ Users ȸ¼ĩòѡИˇɩparams[:id] _ѕĬ̛ Ȁ̫ idå 1ȁTїƊě 6.1.4 ω ̶ȷЛ̛ User.find(1) ̫ɐʔ ʠʣʌЗparams[:id] ѕĬ̫ ɮŪͨ" "1"find ɟ˓_οÌƃ˜тȮǺɗɕDžƻ Ų)5ϱijěÌk*Ċ/users/1 ĵĸƊþTʵƤɯ͈5Šij 7.6̢DZ ЛЍxǠ˜ŹЈų5 params[:id] ̫~ěÀҷ¯ʑ̫ ʠ --action: show controller: users id: '1' ȁTR̀ 7.5 ̫ User.find(params[:id]) ȃ_óĬ id $ 1 ̛̫ȀЁDŽ ij 7.6 ІΦ Users ЬˬĊ̛̫ȀЬəҹҷ /users/1 7.1.3 -öŶ×(æŀö®ʼnÊŲű πʶ̛ȀЬəҹҷƝΒþTʵƤЇҕ5ȷʌǻUϬų̓ij 7.1 ȁ͈̫ʐǜ5µƶҴǙҹҷě User ʬľ ʠƷò̫ѐ͘_оϡ TDD ǜǯ 225 Ĵ 5.4.2 ω ǻUn̛үǺ˜Ѝž Users Ьˬ̷–̫ҹҷјϡ5˜ЍT“˕ž”ҹҷ$o˜ЍЇҕ signup_path˼Ċʨ˜ҹҷ h1 ě title ʜ̫ͭŹɮčʵ͆R̀ 7.6 ɮžR̀ 5.32 ̫ϤŒ˕DZǻ U·Ҧ5 5.3.4 ω̛»̫ full_title ƣÍɟ˓ĭ$ʜӄƝΒ˜Ѝѐ5 R̀ 7.6 ϤŒ̛Ȁ̷–ҹҷ̫˜Ѝ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do subject { page } describe "signup page" do before { visit signup_path } it { should have_content('Sign up') } it { should have_title(full_title('Sign up')) } end end $5˜Ѝ̛ȀЬəҹҷϬɽ  User ʬľžПR̀ 7.5 ̫ show ÌkȃιȆϡʙБɈk describe "profile page" do # Replace with code to make a user variable before { visit user_path(user) } it { should have_content(user.name) } it { should have_title(user.name) } end ǻUϬȏҷR̀ ̫˕ѽȮǺ̷–̫R̀ȃϡĴ˕ѽĊҷЛ̛ user_path ™ĉм̜ìϮϥʣ 7.1Їҕ̛ ȀЬəҹҷ̫ĵĸ˼Ċʨ˜ҹҷŹěʜӄɮčѹÓď̛Ȁ̫ĉŪ υǧ¥µƶ User ʬľҲϬЛ̛ Active Record ȼp̫ User.create ɟ˓ѐΒӎĔЊǻUn̛ӀʐV factoryµƶ̛ȀžПɹɟtū‘ɕȰƯ0ɹŹɫ ǻUϬn̛ Factory Girl ʌ̚ǺӀʐVї gem ɮ̜ thoughtbot “ă̫эGƷò̫ě RSpec ͶbFactory Girl 0Ų)5 ŝӁŁƓДϷDomain-specific Language, DSL̛ʌ̚Ǻ Active Record žПFactory Girl ̫ú˓ NjͮÞn̛Ļěɟ˓Ų)žП̫Ɠǝ~ʄͥіˎɽɯ¬ӀʐV̫^ÑѐĊΛ̫Ź_Őʭn̛ӀʐV̫ӑ Έɹι»ɩlƊþT̺»Ů̫ǁœ*Ō5oŠĴ 9.3.3 ω ҲϬ̚Ǻ ȋ Email ĵĸĆ̷Ĉ̛̫ȀžП ̛ӀʐVƊþTNjхʍ̫ŰǺї͑Ɉk ě˜P̫ gem ʠǻUϬĴ Bundler ̫ Gemfile ʑŠR̀ 7.7 ȁ͈̫R̀ʌůϪ Factory Girlĭ$üɽ ˜Ѝɩȃ_̛» Factory GirlȁTȏŮǂ‘˜Ѝ΍  R̀ 7.7 ȏ Factory Girl ʑ Gemfile 226 ͩ 7 ͥ ̛Ȁ˕ž source 'https://rubygems.org' . . . group :test do . . . gem 'factory_girl_rails', '4.2.1' end . . . ˼ĊěLjƤ ʠѓϡTĚSůϪ $ bundle install Factory Girl ̚Ǻ̫ӀʐVѹwūĴ spec/factories.rb RSpec _οÌÊцїɘV̛Ȁ̷–̫ӀʐVŠ R̀ 7.8 ȁ͈ R̀ 7.8 ʬȝ User ʬľžП̫ӀʐV spec/factories.rb FactoryGirl.define do factory :user do name "Michael Hartl" email "michael@example.com" password "foobar" password_confirmation "foobar" end end factory ɟ˓̫ :user ìɕЗɪĻ ̫R̀Ų)5  User ʬľžП ʑR̀ 7.8 *ĊƊþTĴ˜Ѝ n̛ let ɟ˓ìϮɡ˕ 6.3ě Factory Girl ȼp̫ FactoryGirl ɟ˓ʌ̚ Ǻ User žП let(:user) { FactoryGirl.create(:user) } yɌĊ̫˜ЍŠR̀ 7.9 ȁ͈ R̀ 7.9 ̛ȀЬəҹҷ̫˜Ѝ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do 227 subject { page } describe "profile page" do let(:user) { FactoryGirl.create(:user) } before { visit user_path(user) } it { should have_content(user.name) } it { should have_title(user.name) } end describe "signup page" do before { visit signup_path } it { should have_content('Sign up') } it { should have_title(full_title('Sign up')) } end end ̓ĴlưВ̺ ˜ЍɮčɮŗХ̫Άχ $ bundle exec rspec spec/ ʑR̀ 7.10 *Ċ˜ЍƊþTѫѐ5Νχ R̀ 7.10 Ĵ̛ȀЬəҹҷϱij ʑʜӄěʜŘ app/views/users/show.html.erb <% provide(:title, @user.name) %>

<%= @user.name %>

Ÿʭѓϡ RSpec͆ϻR̀ 7.9 ̫˜ЍɮčþTѫѐ $ bundle exec rspec spec/ n̛ Factory Girl ĊɪɯþTżϳ˜ЍõǶ5їɮ Factory Girl ƀρ̫ήɮɽDZ$*ƫɮ bugõǶ̫ êĭĴ: 6.3.1 ω ̛ʌÊźź̫̀ BCrypt˜Êźͯ˓ІϹŠʶĭ$ǶѬÊź̫ź̀Njҭ͂ϵǶѬÊź̫ѐ ͘_Ƶґ˜Ѝ̫ѓϡɩҖѐǻUþT‚ͮÞ̫ІΦɌõї͑ǧ¥bcrypt-ruby n̛ΰɩĭũcost factorІŲÊźѐ̫͘ΰɩΰɩĭũ̫әϻ~ċ:ů’ǝήɮѬƴĴ̚C̒Ňї͑ІΦNjşc˜Ѝɩ̫ –˕˸æɽȁĈ ˜Ѝџˇ̫ɮѬƴή̛ĴDZ˜ЍɕȰƯ ̛Ȁ̫ź̀ǁƴǻUþTĴ“˜Ѝ̒Ň”ѺΦɘ V config/environments/test.rb ʑ ϡR̀ʌϵ¤ѬƴǶ̫ҕӄ ȏΰɩĭũ̫әϻ~yɌ$ɼƄ ~ȼÛÊź̫ѬƴŠR̀ 7.11 ȁ͈ån˜ЍҀNjƅyɌІΦ*ĊѬƴ̫ȼÛ0ɮNjɪɯ̫ȁTǻƶϿʿ ЙέѹĴ test.rb ɘV ʑR̀ 7.11 ̫Ź R̀ 7.11 $˜Ѝ̒ŇѿɞІΦ BCrypt ΰɩĭũ config/environments/test.rb 228 ͩ 7 ͥ ̛Ȁ˕ž SampleApp::Application.configure do . . . # Speed up tests by lowering bcrypt's cost function. ActiveModel::SecurePassword.min_cost = true end 7.1.4 éL Gravatar }5h0ŐÜ  Ƅωµƶ5 ̣ɯͮҡ̛̫ȀЬəҹҷї ƄωϬŸ˦Ê AŹ ̛Ȁ؈ěrьʞʐƶϱijɩǻ U–˕̫ɮɯ͈̫ŹήɮҹҷƱƏ̫ΔʐȁTǻUɵɩ˜Ѝϱijͪѯ»Źɫ¬Ҍ̫ҹҷΔʐɩoŠ 9.3.3 ω ̫¯ҹƀτŸn̛ TDD ̕ǖ ӊǻUϬĴ̛ȀЬəҹҷ ˦Ê “’̔ѫ̛Љº”̫؈ї؈0͖k Gravatar6̜ Tom PrestonWernerGitHub ̫γćµţGƷòĊϧ AutomatticƷò WordPress ̫“ăɋШGravatar ɮ Ыɿ Ë̛ȀüҲ`ij́ƫƃ˜–γ» Email ĵĸåþn̛ Gravatar þTͮÞ̫ĴΤͤ ʑ̛Ȁ؈Ʒòέ ǐŸ¯ǏëŌ̕ij́`Äϩěū‡üϬn̛̛Ȁ̫ Email ĵĸʐǺ؈̫ URL ĵĸ–γ̫؈ƊþTɯ ͈¬ʌ57 ǻUϹ±Ų) ĉ$ gravatar_for ̫ɟ˓ѕĬȦŲ̛Ȁ̫ Gravatar ؈ŠR̀ 7.12 ȁ͈ R̀ 7.12 ɯ̛͈ȀĉŪě Gravatar ؈̛̫ȀЬəҹҷϱij app/views/users/show.html.erb <% provide(:title, @user.name) %>

<%= gravatar_for @user %> <%= @user.name %>

̓Ĵ̺ ˜ЍɮɮŗХ̫ $ bundle exec rspec spec/ ĭ$іˎŲ) gravatar_for ɟ˓ȁT̛ȀЬəҹҷ_ɯ͈ҌЕȼ͈˜Ѝϱijɼœ̫k̛œʫƊɮþTȬ ϓї͑ҌЕȁT ŲϬȴȾϱij˜Ѝ̫Ҁ әϻǧ¥ȁɽƣÍɟ˓ɘV Ų)̫ɟ˓ѹþT̶ȷ̛ĴXDZ̫ϱij ѐ$5t:Ͱ̕ǻU_ȏ gravatar_for ɎĴ Users ȸ¼ĩžư̫ƣÍɘV Gravatar ̫ӊҹ ɽKΑЗ؈̫ URL ĵĸϬn̛ MD5 Êź̫ Email ĵĸĴ Ruby MD5 Êźͯ˓̜ Digest Ư̫ hexdigest ɟ˓ų̓ 6. Ĵãƴɓ avatar ɮ̫͋ÔсþTɮ G0þTɮ ͑Ì̜̄ʶƼ̝»˜PӁŁ̆ºɮĴϜȝ̠ avatar Ɗ Rϥ Glþι̺ѐҞªэїѸ̞dž5ȁTlþι0ƝΒ̾ѱ avatar ̫DZǜ5 7. Šʔl̫ư̛͘ƮҲϬŌ̕ij́î˜PɘV̫`ǻȹϐln̛ Paperclip Ǽ CarrierWave 229 >> email = "MHARTL@example.COM". >> Digest::MD5::hexdigest(email.downcase) => "1fda4469bcbec3badf5418269ffc5968" Email ĵĸׯœƄ¢ή MD5 Êźͯ˓æׯȁTǻUϬЛ̛ downcase ɟ˓ȏ Email ĵĸтȮǺƄ¢ Džƻ˼ĊŸ`ѨΖ hexdigest ɟ˓ǻUŲ)̫ gravatar_for ɟ˓ŠR̀ 7.13 ȁ͈ R̀ 7.13 Ų) gravatar_for ƣÍɟ˓ app/helpers/users_helper.rb module UsersHelper # Returns the Gravatar (http://gravatar.com/) for the given user. def gravatar_for(user) gravatar_id = Digest::MD5::hexdigest(user.email.downcase) gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}" image_tag(gravatar_url, alt: user.name, class: "gravatar") end end gravatar_for ɟ˓̫ѕĬ~ɮ Gravatar ؈̫ img ‹΁img ʜ̫ͭ class І$ gravataralt Ɠǝ~ɮ̛Ȁ ̫ĉŪžϱϳҬ͇Gʼnn̛̫ƑƧҘЙĩNjïş̓ĴlþTӎЈ ˜ЍɮčþTѫѐ $ bundle exec rspec spec/ ̛ȀЬəҹҷ̫ɐʔŠij 7.7 ȁ͈ҹҷ ɯ͈̫؈ɮ Gravatar ̫әϻij́ĭ$ user@example.com ɮ̻ ̫ Email ĵĸexample.com їŁĉɮҒ̛ʌ&o̫ ǻUЛ̛ update_attributes ɟ˓ìϮ 6.1.5 ωɹɞ ɕȰƯ ̛̫ȀЁDŽ˼ĊƊþTɯ̛͈Ȁ̻ʵ̫ ؈5 $ rails console >> user = User.first >> user.update_attributes(name: "Example User", ?> email: "example@railstutorial.org", ?> password: "foobar", ?> password_confirmation: "foobar") => true ҷ̫R̀ơ̑Ȁ̫ Email ĵĸІ$ example@railstutorial.orgǻƝΒȏї Email ĵĸ̫؈І$5 ʄ2Τ̫ͤ LOGOyɌĊ̫ΔʔŠij 7.8 ȁ͈ ǻUіϬ˦Ê rьʞȃιŰɗ̫ų̓ij 7.1 ̫ʐǜǻUϬn̛ aside ʜͭŲ)rьʞaside ̫ Ź υɮž%gŹ̫ϤŒѐ0þTοǺ gǻUϬȏ aside ʜ̫ͭ class І$ row span4ї0ɮ Bootstrap _̛»̫Ĵ̛ȀЬəҹҷ ˦Êrьʞ̛»̫R̀ŠR̀ 7.14 ȁ͈ 230 ͩ 7 ͥ ̛Ȁ˕ž ij 7.7 ɯ͈әϻ Gravatar ؈̛̫ȀЬəҹҷ /users/1 R̀ 7.14 $̛ȀЬəҹҷ˦Êrьʞ app/views/users/show.html.erb <% provide(:title, @user.name) %>
˦Ê5 HTML Δʐě CSS class ĊǻUŸ̛ SCSS $ЬəҹҷŲ)ʠƻŠR̀ 7.15 ȁ͈˕DZ ĭ$ asset pipeline n̛5 Sass ӀŌ̕ĩȁTʠƻ ȃþTn̛Ɩŝɼΐ̫ɐʔŠij 7.9 ȁ͈ R̀ 7.15 ̛ȀЬəҹҷ̫ʠƻÓȠrьʞ̫ʠƻ app/assets/stylesheets/custom.css.scss . . 231 . /* sidebar */ aside { section { padding: 10px 0; border-top: 1px solid $grayLighter; &:first-child { border: 0; padding-top: 0; } span { display: block; margin-bottom: 3px; line-height: 1; } h1 { font-size: 1.4em; text-align: left; letter-spacing: -1px; margin-bottom: 3px; margin-top: 0px; } } } .gravatar { float: left; margin-right: 10px; } 7.2 å>ĮR ̛ȀЬəҹҷƝΒþTЇҕ5cŹіŰɗҷǻUϬ$Τͤµƶ ˕žϥÞŠij 5.9 ěij 7.10 ȁ͈ “˕ž”ҹҷіˎɽH(Źɣ˓˕žɞ̛Ȁʄω_ų̓Šij 7.11 ȁ͈̫˕žϥÞ˦Ê˕žÉι ĭ$ǻUϬų̓ѫѐΤҹµƶ̛Ȁ̫ÉἰĴƊȏ 6.3.5 ωĴȸ¼ÿ µƶ̛̫Ȁ·ҦĎɼͮÞ̫ɟ˓ɮn̛ db:reset ĚS $ bundle exec rake db:reset іêɕȰƯĊĴɽA΀Ι іϬѿɞ¦ō˜ЍɕȰƯ 232 $ bundle exec rake test:prepare ͩ 7 ͥ ̛Ȁ˕ž ij 7.8 ɯ̛͈Ȁ̻ų؈̛̫ȀЬəҹҷ /users/1 ĴʗA΀Ι іϬѿđ Web ɿËĩіêɕȰƯ̫Ɉkȃι̚ɐ8 7.2.1 æŀö®å>Kħ Ĵ Web ʤʖˎɽےɊȥ˜Ѝ*À˜ЍɮVNj̧ό̫80NjŹɫ¬ҌoŠȂ̘Ѝ“˕ž”ҹҷɩǻUϬ Ĵ˝ϲĩ Їҕїҹҷ˼Ċ¯ºȼBć˓̫ěć˓̫ɕȰʨʙĴї͑ǧ¥ư̛͘Ʈ̫ϥ̓ɮčʵƤ ήʿʭyɌ͘ƮĊѹϬѿŎѝ̫Ɉkn̛ RSpec ě Capybara *ĊTÀҲϬȂÌјϡ̫˜Ѝ̓ĴþT Π¢˜Ѝ̛oοÌȆϡ5 Àҷ̫ͥωƝΒKΑѐ Capybara ЇҕΤҹɩn̛̫Nj̶ϯ̫ú˓˜ ̛̫ɼŐ̫ƊɮЇҕʗҹҷ̫ visit ɟ ˓Capybara ̫ÉιþIҤ:ʶŮіþTņ¢Šij 7.11 ȁ͈̫ϥÞŪʼ˼Ċ˸­ȼBȧ҄ú˓Š visit signup_path fill_in "Name", with: "Example User" . . 8. ɽ˸ɀǷɮĎ˜ųǻ0̾ѱêĭ 233 . click_button "Create my account" ̓ĴǻUϬ¯ºȼBć˓̫ěć˓̫˕žɕȰӎЈ˕žÉιɮčþTʵƤn̛ǻUϬ̛»̫˜Ѝ̷žӑΈ AȁT_ǶǶ¯ʑŠʔlǯʙ̺ɼΐ̫˜ЍR̀Tî˜ЍɘV̫dΦþT̶ȷн»R̀ 7.16ʌ˜Ѝ ˎɽʵ͆ņ¢xǠ̫˕žϥÞǻUЇҕ“˕ž”ҹҷH(0ņ̶ȷ˸­˕žȧ҄Л̛ click_button ɟ ˓їɈkʬȝ̫ƊɮȼBć˓ɕȰ̫ǧ¥ visit signup_path click_button "Create my account" ij 7.9 ˦ÊrьʞƫŲ)5ʠƻ*Ċ̛̫ȀЬəҹҷ /users/1 ҷ̫R̀ͪĈ:ȂÌЇҕ˕žҹҷ˼ĊȼB̩̫͝ć˓˕žxǠ̷ž̫ǻUϬЛ̛ fill_in ɟ˓ņ ¢ć˓xǠTʶʌʬȝȼBć˓ɕȰ̫ǧ¥ visit signup_path fill_in "Name", with: "Example User" fill_in "Email", with: "user@example.com" fill_in "Password", with: "foobar" fill_in "Confirmation", with: "foobar" click_button "Create my account" 234 ͩ 7 ͥ ̛Ȁ˕ž ǻU˜Ѝ̫ɼΐ̴̫ɮϬʨ˜˸­“Create my account”ȧ҄*Ċ͘Ʈ̫ϥ̓ɮčʵƤåǃȼBć˓̫ɕȰɩ µƶɞ̛Ȁ ǃȼBć˓̫ɕȰɩµƶɞ̛Ȁʨ˜ɮɮčµƶ5ɞ̛ȀǻUϬ̛̺Ȁ̫ɕҀɮčò̚5 õÔĴ˜Ѝ ǻUn̛ʿ Active Record žПѹþTĞư̫ count ɟ˓ʌϓóžП̫ɕҀT̛Ȁ$o å $ rails console >> User.count => 0 ij 7.10 “˕ž”ҹҷ̓Ĵ̫ʠũ /signup ̓Ĵ User.count ̫ѕĬ~ɮ 0ĭ$ʄωƷŘǻUіê5ɕȰƯȼBć˓ɕȰɩǻUơʀ̛Ȁ̫ɕҀɮ õ̫ ȼBć˓ɕȰɩǻUơʀ̛Ȁ̫ɕҀňÊ 1 Ĵ RSpec ҷ̫ІǯϬΔć expect ě toǼέě not_to ɟ˓ʌϥѝǻUMć˓̫ɕȰƷţĭ$ї͑ǧ¥ˀчͮÞǻUЇҕ“˕ž”ҹҷ˼Ċ˸­ȼ Bȧ҄ơʀ̛Ȁ̫ɕҀõ visit signup_path expect { click_button "Create my account" }.not_to change(User, :count) ˕DZѫѐϊȠĂǻUþT̺¬expect ȏ click_button ÓďĴ Ļ ìϮ 4.3.2 ωїɮ$ change ɟ˓‚̫̆ʻŌ̕change ɟ˓þȷôìɕͩ ìɕɮžПĉͩ9ɮ Symbolchange ɟ˓_Ĵ 235 expect Ļ ̫R̀ȆϡÀĊ¯ºϹͯĴͩ ìɕЛ̛ͩ9ìɕRϥ̫ɟ˓ѕĬ̫Δʔ0ƊɮЗŠ̫ R̀ expect { click_button "Create my account" }.not_to change(User, :count) _ĴȆϡ click_button "Create my account" ÀĊʭϹͯ User.count ̫Δʔ ij 7.11 “˕ž”ҹҷ̫ʐǜij ʄoǻƯ not_to ɟ˓ϥ͈Ǵ̺»̛ȀɕҀò̚õÔȏ˸­ȧ̫҄R̀Ɏ‘Ļ ̷ǃ:ȏ 236 ͩ 7 ͥ ̛Ȁ˕ž initial = User.count click_button "Create my account" final = User.count expect(initial).to eq final ɻȮǺͮÞ̫ ϡR̀ expect { click_button "Create my account" }.not_to change(User, :count) їʠЙгʌɹҼøR̀0ɹͮ˖˕DZeq ɮ RSpec ȼp̫ɟ˓̛ʌ˜Ѝɮč̷ͪ ȼBć˓ɕȰ̫ǧ¥ěѝć˓ɕȰ̫ǧ¥Ͷbѐ̛ȀɕҀɮõήɮňÊ5 1  visit_signup path fill_in "Name", with: "Example User" fill_in "Email", with: "user@example.com" fill_in "Password", with: "foobar" fill_in "Confirmation", with: "foobar" expect do click_button "Create my account" end.to change(User, :count).by(1) їѾn̛5 to ɟ˓ǻUơʀ˸­ȼBȧ҄ĊїAć˓̫ɕȰþT̛ʌµƶ ɞ̛ȀǻUȏҷ͑ǧ¥ Ɏ‘  describe Ļ Ÿȏ•̛̫R̀Ɏ‘ before Ļ ɼΐnj»̫˕žÉι˜ЍR̀ŠR̀ 7.16 ȁ͈ ǻUі‚5 һѿʐ̛ let ɟ˓Ų)5 submit õҀϥ͈˕žȧ̫҄ɘʄ R̀ 7.16 ˜Ѝ̛Ȁ˕žÉι̫R̀ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do subject { page } . . . describe "signup" do before { visit signup_path } let(:submit) { "Create my account" } describe "with invalid information" do it "should not create a user" do expect { click_button submit }.not_to change(User, :count) 237 end end describe "with valid information" do before do fill_in "Name", with: "Example User" fill_in "Email", with: "user@example.com" fill_in "Password", with: "foobar" fill_in "Confirmation", with: "foobar" end it "should create a user" do expect { click_button submit }.to change(User, :count).by(1) end end end end ĊΛ©ωі_˦ÊɹŐ̫˜Ѝѐ̓Ĵї˜ЍƝΒþTʨ˜̷ǃŐ̫Éιϥ̓ɮčʵƤ5ϋϬnї˜Ѝѫ ѐnjµƶÓďʵ͆‹΁̫˕žҹҷȼB˕žxǠĊҹҷϬтċʵ̫͆ĵĸήŠʔɕȰɮć˓̫іϬµ ƶ ɞ̛Ȁƫū‘ɕȰƯ  ǃ˼5̓Ĵ˜ЍіɮŗХ̫ $ bundle exec rspec spec/ 7.2.2 -ö form_for ǻUƝΒ$̛Ȁ˕žÉιΠ¢5Ѣǃ̫˜ЍR̀ȷʌϬµƶ̛Ȁ˕žϥÞ5Ĵ Rails µƶϥÞþTn̛ form_for ƣÍɟ˓ȦŲ˜ìɕ$ Active Record žП˼Ċn̛žП̫ƓǝʐƶϥÞ̫Ūʼ˕žϥÞ̫ϱijŠ R̀ 7.17 ȁ͈˾ǣ Rails 2.x ̫ЙέϬ˕DZ їѾ form_for n̛̫ɮ <%=...%> Džƻή Rails 2.x n̛ ̫ɮ <%...%> Džƻ R̀ 7.17 ̛Ȁ˕žϥÞ app/views/users/new.html.erb <% provide(:title, 'Sign up') %>

Sign up

<%= form_for(@user) do |f| %> <%= f.label :name %> <%= f.text_field :name %> 238 ͩ 7 ͥ ̛Ȁ˕ž <%= f.label :email %> <%= f.text_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation %> <%= f.submit "Create my account", class: "btn btn-large btn-primary" %> <% end %>
ǻUʌ¯ʑ їAR̀Ĵҷ̫R̀ ǻUn̛5–ҎЋ doЗɪ form_for ĊҷþTк̽ĻήþT `‘ Ļìɕ fRϥїϥÞ <%= form_for(@user) do |f| %> . . . <% end %> ǻU υɣҲ5ϵ Rails ƣÍɟ˓̫Ѹų̓cɮž: form_for ʌЗǻUϬ̾ѱ f žП̫k̛ɮH( Л̛ ϥÞŪʼoŠɘʄŪʼÞѥȧ҄ź̀Ūʼžư̫ɟ˓ɩ̚Ǻ̫ϥÞŪʼ‹΁þT̛ʌІŲ @user ž П̫Ɠǝ0ƊɮЗ <%= f.label :name %> <%= f.text_field :name %> ̚Ǻ̫ HTML ɮ ɽʜĂlabel̫ɘʄŪʼþT̛ʌІŲ User ʬľ̫ name Ɠǝ7.2.3 ω_̺»̚Ǻ̫ HTML̺ѐ̚Ǻ̫ HTML ȃι̕ϵ$H(ŪʼþTІŲƓǝĴʶ*ÀіɽҕӄϬϵ¤ĭ$ˎɽŲ) @user õҀҹҷɣ˓ɯ͈ě˜PʂŲ)̫ųoõҀ ʠ@user ̫~̓Ĵɮ nilȁTŠʔѓϡ˜Ѝ̫Џ _̺»R̀ 7.6 ҂ž˕žҹҷŹ̫˜ЍɮŗХ̫ $ bundle exec rspec spec/requests/user_pages_spec.rb -e "signup page" ѝĚS ̫ -e ìɕȦŲüѓϡȻѝɘʄÓď“signup page”Ūͨ"̫˜Ѝ̛oŠʔɌǺ“signup”³_ѓϡR ̀ 7.16 ̫ȁɽ˜Ѝ Ϭnї˜ЍѫѐĈɩ0ϽҹҷþTʵƤɯ͈ǻUϬĴ new.html.erb ϱijžư̫ new Ìk Ų) @user õҀform_for ɟ˓̫ìɕҲϬ  User žПήǻUϬµƶɞ̛ȀȁTǻUþTn̛ User.new ɟ˓ ŠR̀ 7.18 ȁ͈ 239 R̀ 7.18 Ĵ new Ìk Ų) @user õҀ app/controllers/users_controller.rb class UsersController < ApplicationController . . . def new @user = User.new end end Ų) @user õҀĊ˕žҹҷ̫˜ЍƊþTѫѐ5 $ bundle exec rspec spec/requests/user_pages_spec.rb -e "signup page" Ÿ˦ÊR̀ 7.19 ̫ʠƻϥÞ̫ɐʔŠij 7.12 ȁ͈˕DZǻUŸʭ̛»5R̀ 7.2 ̫ box-sizing ї mixin R̀ 7.19 ˕žϥÞ̫ʠƻ app/assets/stylesheets/custom.css.scss . . . /* forms */ input, textarea, select, .uneditable-input { border: 1px solid #bbb; width: 100%; padding: 10px; margin-bottom: 15px; @include box_sizing; } input { height: auto !important; } 7.2.3 ĮRû HTML Šij 7.12 ȁ͈“˕ž”ҹҷ̓ĴþTʵƤɯ͈5ЗɪR̀ 7.17 ̫ form_for ɟ˓̚Ǻ5ć˓̫ HTML̚Ǻ ̫ϥÞ HTMLþTn̛ Firebug Ǽ˝ϲĩ̫“ʙ̺ˬɘV”ϔÞʙ̺ŠR̀7.20 ȁ͈ʗAΎὠĴɣҲ–Ǐ ǻUüϵЗɼѿϬ̫Δʐ R̀ 7.20 ij 7.12 ϥÞ̫ HTML 240 ͩ 7 ͥ ̛Ȁ˕ž
ij 7.12 ˕ž̛Ȁ̫ϥÞ /signup 241 ҷ̫R̹̣̀5“ҁºʈʜauthenticity token”̷–̫ HTMLRails n̛ҁºʈʜʌқʴлͤИˇaѭ cross-site request forgery, CSRFɍ­Šʔlžҁºʈʜdz—жþTҘЙ  Stack Overflow Τͤ ̫ Understand Rails Authenticity Token! ɘїͳɘͥKΑ5ҁºʈʜ̫Ƙkê̕îѿϬDZ) ҷ̺ ϥÞ̫ŪʼˀчR̀ 7.17 ěR̀ 7.20 *ĊǻUþT̺»Š̫ ERb R̀ <%= f.label :name %> <%= f.text_field :name %> ̚Ǻ̫ HTML ɮ ҷ̫ ERb R̀ ij 7.13 ņ¢5ɘʄŪʼěź̀Ūʼ̫ϥÞ <%= f.label :password %> <%= f.password_field :password %> ̚Ǻ̫ HTML ɮ 242 ͩ 7 ͥ ̛Ȁ˕ž
Šij 7.13 ȁ͈ɘʄŪʼtype="text"_̶ȷɯ͈ņ¢̫Źήź̀Ūʼtype="password"Ń:ů ’άϛ_ѳ̱ъ‘̫Ź Ĵ 7.4 ω ǻU_KΑ*ȁTþTµƶ̛Ȁ’Я: input ‹΁̫ name Ɠǝ . . . ij 7.14 ˕žŗХĊ̫ҹҷʐǜij Rails _T name Ɠǝ̫~$Ҏ̛Ȁъ‘̫Ź$~ʐǺ ĉ$ params ̫ Hash̛ʌµƶ̛Ȁûŏ  ѿϬ̫ʜͭɮ formǻUn̛ @user žПʌµƶ form‹΁ĭ$ʿ Ruby žПѹ̾ѱŮȁƓ̫ͶìϮ 4.4.1 243 ωȁT Rails ̾ѱ @user ȁƓ̫Ͷɮ User ή@user Rϥ̫ɮɞµƶ̛̫ȀRails ̾ѱϬn̛ POST И ˇɟ˓їʵɮµƶɞžПȁҲ̫ HTTP ИˇìϮɡ˕ 3.3
̺ class ě id ƓǝǻU̓Ĵ–˕̫ɮ action="/users" ě method="post"ІŲїƓǝĊ Rails Ɗ_ċ /users ĵĸòѡ  POST Иˇȷʌ̫ω_KΑїИˇC̫̚ɐʔ 7.3 å>|ň ϝ˼ ωœʫ̫KΑ5ij 7.12 ϥÞ̫ HTML ΔʐìϮR̀ 7.20ѐ˕žŗХɩȃιɹş̫̕ϵїϥ Þ̫k̛ʄωǻU_Ĵ˕žϥÞ ņ¢ Ać˓̫ɕȰȼBϥÞĊҹҷ_тċ˜PҹҷήɮѕĬ“˕ ž”ҹҷɯ͈ AҌЕȼ͈xǠҹҷ̫ʐǜijŠij7.14 ȁ͈ 7.3.1 ^â™-öûĮR ĬҾ  7.1.2 ω ̫ŹĴ routes.rb ІΦ resources :users *ĊìϮR̀ 7.3Rails ư̛͘ƮƊ þTĞưϥʣ 7.1 ͨć REST ʖʐ̫ URI ĵĸ5 υʌЗòѡ» /users ĵĸ̫ POST Иˇɮ̜ create Ìk Ō̫̕Ĵ create Ìk ǻUþTЛ̛ User.new ɟ˓n̛ȼB̫ɕȰµƶ ɞ̛ȀžПƉЍū‘ɕȰ ƯŗХĊŸѿɞ˪ʘ“˕ž”ҹҷŠЄЇŴѿɞņ¢˕žxǠǻUʌ̺ ̚Ǻ̫ form ‹΁ Ĵ 7.2.3 ω KΑѐїϥÞ_ċ /users ĵĸòѡ POST Иˇ ˦ÊR̀ 7.21 *ĊR̀ 7.16 žć˓ɕȰ̫˜ЍƊþTѫѐ5R̀ 7.21 ŸʭЛ̛5 render ɟ˓ͩ n̛ɩɮ$5Ƚ‘ƎѸϱijìϮ5.1.3 ωѐŠlȁϮĴȸ¼ĩ̫Ìk 0þTn̛їɟ˓ĈɩǻU 0}ʶR̀KΑ5 if-else ¯ɊΔʐ̛̫˓ ʢȰ @user.save ̫ѕĬ~¯ºƠ̄̕Ȁū‡ǺÉěŗХї͑ ǧ¥ū‡ǺÉɩѕĬ~$ trueŗХɩѕĬ~$ false R̀ 7.21 Ō̕ū‡ŗХ̫ create ÌkіιŌ̕ū‡ǺÉ̫ǧ¥ app/controllers/users_controller.rb class UsersController < ApplicationController . . . def create @user = User.new(params[:user]) # Not the final implementation! if @user.save # Handle a successful save. else render 'new' end 244 ͩ 7 ͥ ̛Ȁ˕ž end end ̢DZR̀ 7.21 ̫˕ѽїƫɮɼΐ̫ų̓ɟƻc̓ĴےŒ̛ɼΐ̂_Ĵ 7.3.2 ω ų̓ ǻUϬųҠ̫Ɉk ȼB Ać˓̫˕žɕȰїʠȃιɹş̫̕ϵR̀ 7.21 ̫k̛ΔʔŠij 7.15 ȁ ͈ƱѸŰɗ̫ЛЍxǠŠij 7.16 ȁ͈ ij 7.15 ˕žŗХ ҷǻUʌ¯ʑ ЛЍxǠ Иˇìɕ Hash ̫ user Ѹ¯Šij 7.16Ttž Rails Ō̕ϥÞ̫ѐ͘ɽɹ˧ ɳĵϻЉ "user" => { "name" => "Foo Bar", "email" => "foo@invalid", "password" => "[FILTERED]", "password_confirmation" => "[FILTERED]" } Ĵ 7.1.2 ω ƊЗѐparams Hash Óď5ʿʭИˇ̫xǠoŠċ /users/1 òѡ̫Иˇparams[:id] ̫~Ɗ ɮ̛Ȁ̫ idå 1ȼBϥÞòѡ POST Иˇɩparams ³ɮ Ɩŝ̫ HashƖŝ Hash Ĵ 4.3.3 ω n̛ȸ¼ 245 ÿKΑ params ɩ̛ѐҷ̫ЛЍxǠЗɪȼBϥÞĊRails _ʐƶ ĉ$ user ̫ Hash˜Ҏɮ input ʜ̫ͭ name Ɠǝ~ìϮR̀ 7.17Ҏžư̫~ɮ̛Ȁņ¢̫ŪʼɘʄoŠ ij 7.16 ˕žŗХɩ̫ЛЍxǠ ВŪʼ name Ɠǝ̫~ɮ user[email]ŮRϥ̫Ɗɮ user Hash ̫ email ‹΁ ϝ˼ЛЍxǠ ̫ҎɮŪͨ"DžƻѐæT Symbol Džƻ`ѨΖ Users ȸ¼ĩparams[:user] їƖŝ̫ HashųҠƊɮ User.new ɟ˓µƶ̛ȀȁҲ̫ìɕ~ǻUĴ 4.4.5 ω KΑѐ User.new ̛̫˓R̀ 7.21 Ÿʭ̛»5їɟ˓0ƊɮЗŠ̫R̀ @user = User.new(params[:user]) ŃʄͪĈ: @user = User.new(name: "Foo Bar", email: "foo@invalid", password: "foo", password confirmation: "bar") Ĵ Rails *À̫̂ʄ n̛ 246 ͩ 7 ͥ ̛Ȁ˕ž @user = User.new(params[:user]) Ɗϡ5cәϻǧ¥ї̛͑˓ƫů’ҲϬѼ̛Оǵ̫Ō̕ѐ͘ѵǢDZ̛ȀʹɌ͘Ʈ̫ɕȰƯĴ Rails 4.0 їϡR̀_Ȓ¬ƸƤŠij 7.15 ěij 7.16 ȁ͈їʠƊů’5wҧгϮǻUþT̺ ˜Ѝɮčɮŗ Х̫ $ bundle exec rspec spec/requests/user_pages_spec.rb \ -e "signup with invalid information" 7.3.2 4wVÇ ǻUĴ 4.4.5 ω ȼ»ѐ mass assignmentn̛  Hash ¶ţÔ Ruby õҀoŠҷїϡR̀ @user = User.new(params[:user]) # Not the final implementation! ҷїϡR̀ ̫˕ѽʌοR̀ 7.21Зɪїɮɼΐ̫ų̓ɟƻĭ$¶ţÔɗ params Hash ɮÙ¯äҧ̫ ɦ¶ţÔƊ_ơ̑ȀȼB̫ȁɽɕȰ`ѨΖ User.new ɟ˓€ІҦ5Àѝ̫ƓǝUser ʬľіÓď admin Ɠ ǝ̛ʌʜЉΤ̫ͤͰ̕ĕǻU_Ĵ 9.4.1 ωʑїƓǝϬȏїƓǝІ$ trueƊϬĴ params[:user] Óď admin='1'їѐ͘þTхɫ̫n̛ curl ї͑ĚSϡ HTTP ŴȀͦų̓Δʔɮ ȏɗ params `ѨΖ User.new Τ̫ͤX ̛ȀѹþTĴИˇ Óď admin='1' ʌϓóͰ̕ĕʈҤ Ĵ Rails ̫*À̂ʄ þTĴʬľƏ n̛ attr_accessible ɟ˓ϵ¤їҕӄcĴ Rails 4.0 ȹϐ̫ɟ˓ɮ Ĵȸ¼ĩƏn̛ ͑ý‚“„Ŋìɕ”strong parameter̫ȎʅїȎʅþTȦŲҲϬĠAИˇìɕŠЄ`‘ ĠAИˇìɕήŠʔȧ˽ҷ̫ɟƻ`‘ɗ params Hash͘Ʈ_Ȓ¬ƸƤȁT̓Ĵ̫ Rails ͘Ʈәϻ ǧ¥ƝΒŅf mass assignment ˱˗5 ʄoǻUҲϬ params Hash Óď :user ‹΁ήüŠЄ`‘ nameemailpassword ě password_confirmation ƓǝȁҲR̀Š params.require(:user).permit(:name, :email, :password, :password_confirmation) їϡR̀_ѕĬ  params HashüÓďŠЄn̛̫ƓǝήŠʔˎɽȦŲ :user ‹΁_Ȓ¬ƸƤ $5n̛ɟtþTŲ) ĉ$ user_params ̫шÍɟ˓ѕĬȁҲ̫ Hashїɟ˓ü_Ĵ Users ȸ¼ĩ Ѹn̛ҲϬɷҳΖ̛ȀȁTǻUþTn̛ Ruby ̫ private ɟ˓ȏїɟ˓І$͐ɽk̛ŁŠR̀ 7.22 ȁ͈ǻU_Ĵ 8.2.1 ω ɹГΎ̫KΑ private R̀ 7.22 Ĵ create Ìk n̛„Ŋìɕ app/controller/users_controller.rb class UsersController < ApplicationController . . . def create 247 @user = User.new(user_params) if @user.save # Handle a successful save. else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end ˦Ê5ѝR̀Ċ҂žć˓ɕȰ̫˜ЍưВþTѫѐ5 $ bundle exec rspec spec/requests/user_pages_spec.rb \ -e "signup with invalid information" 7.3.3 å>Îûŧł¾ā1« Ō̕˕žŗХ̫ɼĊ ʷǻUϬʑ ҌЕȼ͈xǠЗɪ˕žŗХ̫êĭәϻǧ¥ Rails _ɯ͈їʠ̫ xǠŃ: User ʬľ̫ɕȰӎЈʆ¼ų̓&oũǻUЍ̛̽ć˓̫ Email ĵĸěґƴч̫̿ź̀µƶ̛Ȁ ̺̺_ò̚H( $ rails console >> user = User.new(name: "Foo Bar", email: "foo@invalid", ?> password: "dude", password_confirmation: "dude") >> user.save => false >> user.errors.full_messages => ["Email is invalid", "Password is too short (minimum is 6 characters)"] Šȁ͈errors.full_message žПɮ ҌЕxǠ΍Ǻ̫ɕ΍ěҷ̫ȸ¼ÿžЏͶbR̀ 7.21 ̫ R̀0ɣ˓wư̄Ȁ_̚Ǻ ҟƓĴ @user žП̫ҌЕxǠɕ΍ŠʔϬĴ˕žҹҷɯ͈їAҌЕǻU ҲϬ˪ʘ ҌЕxǠƎѸϱijŠR̀ 7.23 ȁ͈ɼş$їAҌЕxǠΠ¢˜ЍǻU_ȏїXË̢kΌ 1ГǧìϮ 7.6 ω˕DZїƎѸϱijüɮɵɩn̛ǻU_Ĵ 10.3.2 ω Π¢ɼΐ̂ʄ R̀ 7.23 Ĵ˕žϥÞÀɯ͈̫ҌЕȼ͈xǠ app/views/users/new.html.erb <% provide(:title, 'Sign up') %>

Sign up

248 ͩ 7 ͥ ̛Ȁ˕ž
<%= form_for(@user) do |f| %> <%= render 'shared/error_messages' %> . . . <% end %>
˕DZĴҷ̫R̀ ˪ʘ̫ƎѸϱijĉ$ shared/error_messagesїѾ̛»5 Rails ̫ ·Ų ŠʔƎѸ ϱijϬĴŐȸ¼ĩ n̛³ȏŮūɎĴҒ̫ shared ̴DŽї·Ų 9.1.1 ωі_ŸKΑǻUҦ5Ϭ ɞƶ _error_messages.html.erb ɘV*ŏіϬɞƶ app/views/shared ɘVřҌЕȼ͈xǠƎѸϱij ̫ŹŠR̀ 7.24 ȁ͈ R̀ 7.24 ɯ͈ϥÞҌЕȼ͈xǠ̫ƎѸϱij app/views/shared/_error_messages.html.erb <% if @user.errors.any? %>
The form contains <%= pluralize(@user.errors.count, "error") %>.
    <% @user.errors.full_messages.each do |msg| %>
  • * <%= msg %>
  • <% end %>
<% end %> їƎѸϱij̫R̀n̛5©*Àˎ̛ѐ̫ Rails/Ruby Δʐіɽɞɟ˓ͩ ɞɟ˓ɮ countŮ̫ѕ Ĭ~ɮҌЕxǠ̫ɕҀ >> user.errors.count => 2 ͩ9ɞɟ˓ɮ any?Ůě empty? ̫k̷̛ñ >> user.errors.empty? => false >> user.errors.any? => true 249 ͩ ʭn̛ empty? ɟ˓ɮĴ 4.2.3 ω̛ĴŪͨ" Mҷ̫R̀þT̺¬empty? 0þ̛Ĵ Rails ҌЕxǠ žПŠʔžП$͝ƊѕĬ trueč³ѕĬ falseany? ɟ˓Ɗɮóñ empty? ̫ѕĬ~ŠʔžП ɽ ŹƊѕĬ trueˎŹ³ѕĬ falseҼtЗ countempty? ě any? ѹþT̛Ĵ Ruby ɕ΍Ĵ 10.2 ω _şşĵKΑїɟ˓ ij 7.17 ˕žŗХɩɯ͈̫ҌЕȼ͈xǠ іɽ ˀчɞ̫ɟ˓ɮ pluralizeĴȸ¼ÿ әϻþ̛ѐǻUþTƼ‘ ActionView::Helpers::TextHelper ʬĻÊцїɟ˓ 9 >> include ActionView::Helpers::TextHelper >> pluralize(1, "error") => "1 error" >> pluralize(5, "error") => "5 errors" Šȁ͈pluralize ɟ˓̫ͩ ìɕɮɗɕѕĬ~ɮїɕŪěͩ9ìɕɘʄ΍ćĴ гʵ̫͆ÞŎɕ Džƻpluralize ɟ˓ɮ̜Éιǁœ̫тΦĩinflectorų̫̓тΦĩ̾ѱǚ(Ō̕œŐɕÞЋ̫ÞŎɕõ Ȯ̙πɮ Aϰ³̫õȮɟƻ 9. ǻ*ȁT̾ѱϬƼ‘ ActionView::Helpers::TextHelper ʬĻɮĭ$ǻĴ Rails API ʙ5 pluralize ̫ɘʦ 250 ͩ 7 ͥ ̛Ȁ˕ž >> pluralize(2, "woman") => "2 women" >> pluralize(3, "erratum") => "3 errata" ȁTn̛ pluralize ɟ˓ĊŠ̫R̀ <%= pluralize(@user.errors.count, "error") %> ѕĬ~Ɗɮ "0 errors""1 error" Ǽ "2 errors"ͪÞŎɕDžƻó¤:ҌЕ̫ɕҀїʠƊþTѵͶb "1 errors" ї͑eΈ̫ҌЕ5їɮΤΗ ƤϮ̫ҌЕ* ˕DZR̀ 7.24 і$  div ʜͭȦŲ5 error_explanation idþ̛ʌʠƻÔҌЕȼ͈xǠĴ 5.1.2 ω KΑѐCSS T # ƷŘ̫ϰ³ɮ̛ʌΖ id ˦Êʠƻ̫¬ҌɩRails і_οÌȏɽҌЕ̫ŪʼÓďĴ  class $ field_with_errors ̫ div ‹΁ ǻUþT¹̛ї id ě class $ҌЕȼ͈xǠ˦ÊʠƻȁҲ̫ SCSS ŠR̀ 7.24 ȁ͈R̀ 7.25 n̛ Sass ̫ @extend ®ɕƼ‘5 control-group ě error ʠƻϰ³үć˦ÊʠƻĊŠʔȼBŗХҌЕxǠ ě¬Ҍ̫ŪʼƊ_ɯ͈$ΆχŠij 7.17 ȁ͈ҌЕxǠ̫ɘʄɮŃ:ʬľɕȰӎЈοÌ̚Ǻ̫ȁTŠʔlyɌ 5ӎЈϰ³oŠEmail ĵĸ̫ʣƻź̫̀ɼƄґƴҌЕxǠƊ_οÌõÔͨćyɌĊ̫ϰ³ R̀ 7.25 ҌЕȼ͈xǠ̫ʠƻ app/assets/stylesheets/custom.css.scss . . . /* forms */ . . . #error_explanation { color: #f00; ul { list-style: none; margin: 0 0 18px 0; } } .field_with_errors { @extend .control-group; @extend .error; } ǻUþTѫѐҷ̫ɟ˓ʬȝR̀ 7.16 ҂žć˓ɕȰ̫˜Ѝѐ͘ʌ̺ ʄωΠ̫͘ɐʔ Ĵ˝ϲĩ Ї ҕ“˕ž”ҹҷH(0ņ̶ȷ˸­“Create my account”ȧ҄ΔʔŠij 7.18 ȁ͈ɤ˼“˕ž”ҹҷþTʵƤn̛ 5̷ư̫˜Ѝ0ưВþTѫѐ5 251 $ bundle exec rspec spec/requests/user_pages_spec.rb \ > -e "signup with invalid information" ij 7.18 Їҕ“˕ž”ҹҷĊ̶ȷ˸­“Create my account”ȧ̫҄ɐʔ 7.4 å>¬K  ωƝΒŌ̕5ȼBć˓ɕȰ̫ǧ¥ʄωǻUϬŰǺ˕žϥÞ̫ÉιŠʔȼB̫ɕȰć˓Ɗơ̑Ȁū‘ ɕȰƯǻUƉЍwư̄ȀŠʔwūǺÉ̛Ȁ̫ɕȰƊ_ū‘ɕȰƯ ˼ĊΤҹ_тċ´˕ž̛Ȁ̫Ьə ҹҷҹҷ _ɯ͈ ʮђxǠʐǜijŠij 7.19 ȁ͈Šʔwư̄ȀŗХ5ƊB̜ ωų̫̓ÉιŌ̕ 7.4.1 …Èûå>ĮR ϬŰǺ˕žϥÞ̫ÉιǻUϬȏR̀ 7.21 ̫˕ѽѸ¯ȮǺ̷ư̫Ō̕R̀̓ĴžȼBć˓ɕȰ̫˜Ѝіɮ ŗХ̫ $ bundle exec rspec spec/requests/user_pages_spec.rb \ > -e "signup with valid information" 252 ͩ 7 ͥ ̛Ȁ˕ž ˜Ѝ*ȁT_ŗХɮĭ$ Rails Ō̕Ìk̫әϻɟƻɮ˪ʘϱijþɮ create Ìkіˎɽ0ưВɽžư ̫ϱij̷ñ̫ǻUϬтċ˜P̫ҹҷɼć̫̕тċҹҷɮ´µƶ̛Ȁ̫Ьəҹҷʨ˜ɮčтċʵ͆ҹҷ̫ ˜Ѝ_̢kΌ1ìϮ 7.6 ωcreate Ìk̫R̀ŠR̀ 7.26 ȁ͈ ij 7.19 ˕žǺÉĊɯ͈̫ҹҷʐǜij R̀ 7.26 create Ìk̫R̀Ō̕5wūěтċɈk app/controllers/users_controller.rb class UsersController < ApplicationController . . . def create @user = User.new(user_params) if @user.save redirect_to @user else render 'new' end 253 end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end ˕DZтċĵĸǻU̶ȷ¢5 @userήˎ̛ user_pathRails _οÌтċ»̛Ȁ̫Ьəҹҷ ʑR̀ 7.26 Ċ˕žϥÞƊþTʵƤn̛5lþTѓϡ˜ЍӎЈ  $ bundle exec rspec spec/ 7.4.2 Flash è« ӎЈć˓ɕȰɮčιŒʵ͆ȼB*ÀǻUіϬʑ  Web ư̛͘Ʈœѹ_ų̫̓Éι ĴтċĊ̫ҹҷ ɯ͈ ˟ǠїѾǻUϬɯ͈̫ɮ ʮђɞ̛Ȁ̫˟ǠŠʔЇҕ5˜PҹҷǼέ½ɞ5ҹҷї˟Ǡt_˟ ŗĴ Rails ї͑Éιɮѫѐ flash õҀų̫̓flash Ɗˆғū ʠüɮɵɩū‡̫ɕȰflash õҀ̫ ~˜ųɮ  HashlþιіЁnj4.3.3 ω ǻUĴȸ¼ÿ Ѱè5 ĉ$ flash ̫ Hash $ rails console >> flash = { success: "It worked!", error: "It failed." } => {:success=>"It worked!", error: "It failed."} >> flash.each do |key, value| ?> puts "#{key}" ?> puts "#{value}" >> end success It worked! error It failed. ǻUþTȏɯ͈ Flash ˟Ǡ̫R̀ʑư̛͘Ʈ̫ƞƎїʠɗΤͤĴҲϬ̫ɩ|Ɗ_ɯ͈˟Ǡ5ŠR̀ 7.27 ȁ͈R̀ 7.27 ˥ć5 HTML ě ERb R̀ɽ˸47.6 ω ̫Ό1_јϡѿʐ R̀ 7.27 ȏ flash ˟Ǡ̷–̫R̀ʑΤ̫ͤƞƎ app/views/layouts/application.html.erb . . 254 ͩ 7 ͥ ̛Ȁ˕ž . <%= render 'layouts/header' %>
<% flash.each do |key, value| %>
<%= value %>
<% end %> <%= yield %> <%= render 'layouts/footer' %> <%= debug(params) if Rails.env.development? %>
. . . R̀ 7.27 _$ʿ  Flash ˟ǠȽ‘  div ʜͭƫȏ CSS class ȦŲ$˟Ǡ̫ͶľoŠŠʔ flash[:success] = "Welcome to the Sample App!"Ѷ(ҷ̫R̀ <% flash.each do |key, value| %>
<%= value %>
<% end %> ̚Ǻ̫ HTML Š
Welcome to the Sample App!
˕DZҎ :success ɮ SymbolĴȽ‘ʬʎ*ÀERb _οÌƃ˜тȮǺŪͨ" "success"ǻUѰè5ȁ ɽþι¬̫̓ Flash ˟Ǡїʠǃ˟ǠūĴɩȃιɯ͈Ĵ 8.1.5 ω _n̛ flash[:error] ɯ̨͈DŽŗХ˟ Ǡ10 ʨ˜ҹҷ ɮčɯ͈5ʵ̫͆ Flash ˟Ǡ̫˜Ѝ̢kΌ1ìϮ 7.6 ωĴ create Ìk Ζ flash[:success] Э~ ʮђxǠĊŠR̀ 7.28 ȁ͈ї˜ЍƊþTѫѐ5 R̀ 7.28 ˕žǺÉĊɯ͈ Flash xǠ app/controllers/users_controller.rb class UsersController < ApplicationController . . . def create @user = User.new(user_params) if @user.save 10. ˜ųǻU̻ʵǯ̛̫ɮ flash.nowflash ě flash.now *ҖіɮɽΎǎƛº̫ĊΛ_KΑ 255 flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end 7.4.3 Ÿáå> ̓ĴǻUþT˕ž ̺̺»̴À$ʴȁų̫̓Éι̛Ȁ̫ĉŪn̛“Rails Tutorial”Email ĵĸn̛ “example@railstutorial.org”˕žǺÉĊҹҷ ɯ͈5 ïş̫ʮђxǠxǠ̫ʠƻɮ̜ 5.1.2 ω ʑ̫ Bootstrap ʤʖȼp̫ .success class ų̫̓Šij 7.20 ȁ͈Šʔlɣ˓˕žȼ͈ Email ĵĸƝΒn̛И ͆wlѓϡ5 7.2 ω ̫ rake db:reset ĚS˼Ċ½ɞҹҷFlash ˟ǠƊ_˟ŗ5Šij 7.21 ȁ͈ ǻUіþTʨʙ ɕȰƯ͆w̻̫µƶ5ɞ̛Ȁ $ rails console >> User.find_by(email: "example@railstutorial.org") => # 7.4.4 ŞĢHõòvšŸe SSL µƶ5 User ʬľų̓5˕žÉι*Ċ̓ĴþTȏ͈o͘ƮѸΧ»̚C̒Ň 5Šʔlˎɽȧ˽ͩ 3 ͥͥŘ KΑ ̫ŹІΦ̚C̒Ň̫Џ̓ĴɼşĬѐŘëІΦ ѸΧ̫ɩ|ǻUі_Ʒđžů’ŝȷƏSecure Sockets Layer, SSl11ÝϿ̫Ɋȥ͆w˕žѐ̫͘ů’˜ųǻU_’ͤѹƷđ SSLїʠ̛Ą̫̏DŽìϮͩ 8 ͥ0_Njů’5ήіþTѵ_ЏÎȥsession hijacking̫ò̚ìϮ 8.2.1 ω ĴѸΧ*ÀlưВȏʄͥų̫̓Éιćƫ» master ¯Ɋ $ git add . $ git commit -m "Finish user signup" 11. ʣʌЗSSL ̓Ĵ̫͖ęɮ TLSTransport Layer Securityů’`ъƏÝϿѐGUƝΒ1ǭ5 SSL їĉŪ 256 $ git checkout master $ git merge sign-up ͩ 7 ͥ ̛Ȁ˕ž ij 7.20 ˕žǺÉĊɯ͈̫ҹҷҹҷ ɽ  Flash ˟Ǡ ˼ĊǻUϬІΦ ǁ¼Ĵ̚C̒Ň n̛ SSLїѾǻUϬΠщ̫ɘVɮ config/environments/ production.rb˦Ê̫ІΦŠR̀ 7.29 ȁ͈ R̀ 7.29 ІΦ͘ƮĴ̚C̒Ň Ʒđ SSL config/environments/production.rb SampleApp::Application.configure do . . . # Force all access to the app over SSL, use Strict-Transport-Security, # and use secure cookies. config.force_ssl = true . . . end 257 ij 7.21 ½ɞҹҷĊ Flash ˟ǠƊϮ5 ǻUϬȏїʭyɌȼB» Git NƯ ˼ĊŸȹѡ» Herokuȁ‚̫ІΦȃι̚ɐ $ git commit -a -m "Add SSL in production" $ git push heroku ˼ĊǻUіϬĴ̚C̒Ň ѓϡɕȰƯю͗Ĕ̾ Heroku ǻUƶ͢5 User ʬľ $ heroku run rake db:migrate ȆϡїĚSĊlþι_nj» AÉιƳƹ̫ϸĔȼ͈̓ĴþT̶ȷǗϱїAϸĔ ɼĊ ʷǻUϬĴљ͘ɿËĩʖІ SSLĴ̚C̒Ň ʖІž SSL ̫ɊȥNjӖ˻0NjŹɫ¬ҌήіϬ$ ŁĉШ3 SSL ͭĉЈ2Ƭşn̛ Heroku ȼp̫9ΈŁĉþT̶ȷn̛ Heroku ̫ SSL ͭĉЈ2їͯɮ Heroku Ʃÿ̫ ̆ǝŠʔlϬ$οƜ̫ŁĉoŠ example.comƷđ SSLƊɣ˓Dôїt¹̫ɿË 5іϬοϡɿ AІΦ̫Ӗ˻™g̫ʷӏĴ Heroku –: SSL ̫ɘʦ ɽЗɪ TȁɽƘknj»̫ɼΐΔʔɮĴ̚CɿËĩþTʵƤn̛˕žϥÞ5Šij 7.22 ȁ͈ $ heroku open 258 ͩ 7 ͥ ̛Ȁ˕ž ˕DZĴij 7.22 ѫƤɯ͈$ http:// ̫ĵɟ̓Ĵɯ͈̫ɮ https://Ɗɮїӆŏ̫“s”ЈɪǻUʵĴn ̛ SSL ̓ĴlþTȄƷ˕žҹҷ˕ž ɞ̛Ȁ5Šʔѯ»ҕӄѓϡ heroku logsƉЍn̛ Heroku ̫ɥǒɘVȵ Ҍ ij 7.22 ΋ʵƤѓk̫˕žҹҷ 7.5 ŒĘ ų̓˕žÉιž͈o͘ƮʌЗͯɮónj5Njœ̫јƒϝ˼̓Ĵіˎų̻̓ʵɽ̛̫ÉιѐǻUæ$ĊΛÉι ̫ƷòŞŲ5ļų̫Ń̈́ͩ 8 ͥǻU_ų̛̓Ą̏DŽѠ¬ÉιŰǺɗсYӎЈʆ¼ͩ 8 ͥǻU_ų ̓ɹɞ̛ȀGxǠ̫ÉιǻUі_ų̓Ͱ̕ĕ·Ҧ̛Ȁ̫ÉιїʠȃͯɮŰɗ̫ų̓5ϥʣ 7.1 ȁ² Users Ьˬ̷–̫ REST ÌkɼĊǻUі_ĴĆÌk ų̓ʈҤӎЈÉιȼÛΤ̫ͤů’ 7.6 Ė 1. TR̀ 7.30 $ϗʄӎЈ Ĵ 7.1.4 ω Ų)̫ gravatar_for ƣÍɟ˓ɮčþTȷôĉ$ size ̫þ ѥìɕŠЄĴϱij n̛Ͷb gravatar_for user, size: 40 їʠ̫Džƻ 2. Π¢˜Ѝʨ˜R̀ 7.23 ų̫̓ҌЕȼ͈xǠþTì˽R̀ 7.31 259 3. ѼóΠ¢˜Ѝ̫ɟƻǼέͪ»͘Ʈ¬ҌĊŸϤɒӎЈ R̀ 7.32 ̫˜ЍþT͆w create Ìk wư̄Ȁ*ĊҼ¹̫т»5̛ȀЬəҹҷR̀ 7.32 ̛»5 Capybara ȼp̫ have_selector ɟ ˓їɟ˓þT˜Ѝ HTML ʜͭѫѐ CSS class ȦŲɮč¬̓Ĵҹҷ  4. ǻUÀҷЗѐR̀ 7.27 Flash ˟Ǡ̷–̫R̀ɽ˸4ǻUϬƠ̇R̀ 7.33 ̫R̀ѓϡ˜Ѝ̺ n̛ content_tag ƣÍɟ˓*Ċɐʔɮč ʠ R̀ 7.30 ѿɞŲ) gravatar_for ɟ˓ŠЄȷôþѥ̫ size ìɕ app/helpers/users_helper.rb module UsersHelper # Returns the Gravatar (http://gravatar.com/) for the given user. def gravatar_for(user, options = { size: 50 }) gravatar_id = Digest::MD5::hexdigest(user.email.downcase) size = options[:size] gravatar_url = "https://secure.gravatar.com/ avatars/#{gravatar_id}.png?s=#{size}" image_tag(gravatar_url, alt: user.name, class: "gravatar") end end R̀ 7.31 ҌЕȼ͈xǠ˜Ѝ̫ìά spec/requests/user_pages_spec.rb . . . describe "signup" do before { visit signup_path } . . . describe "with invalid information" do . . . describe "after submission" do before { click_button submit } it { should have_title('Sign up') } it { should have_content('error') } end . . . 260 ͩ 7 ͥ ̛Ȁ˕ž R̀ 7.32 ž create Ìk wư̄ȀɈk̫˜Ѝ spec/requests/user_pages_spec.rb . . . describe "with valid information" do . . . describe "after saving the user" do before { click_button submit } let(:user) { User.find_by(email: 'user@example.com') } it { should have_title(user.name) } it { should have_selector('div.alert.alert-success', text: 'Welcome') } end . . . R̀ 7.33 n̛ content_for Π¢̫ Flash ˟ǠϱijR̀ app/views/layouts/application.html.erb . . . <% flash.each do |key, value| %> <%= content_tag(:div, value, class: "alert alert-#{key}") %> <% end %> . . . 261 ĉ 8 ć ú¥hŖA ͩ 7 ͥƝΒų̓5˕žɞ̛Ȁ̫ÉιʄͥǻUϬ$Ɲ˕ž̛̫Ȁȼp̨DŽěѠ¬Éιų̨̓DŽÉι*ĊƊþ TʢǪ̇̄DŽ̉ǙěǃÀ̛Ȁ̫сYŲ¼Τ̫ͤŹ5oŠʄͥǻU_ɹɞΤ̫ͤŘѸɯ͈“̨DŽ”Ǽ“Ѡ¬”҈ ȷTî»GЬəҹҷ̫҈ȷ Ĵͩ 10 ͥ _ʢȰǃĄ̀DŽ̛Ȁ̫ id µƶ–γ»ї̛Ȁ̫ǎà Ĵͩ 11 ͥǻU_ų̓ǃĄ̀DŽ̛Ȁ–˕˜P̛Ȁ̫Éιų̓*ĊĴӊҹƊþTɯ͈ϧ–˕̛Ȁòϥ̫ǎà5 ų̨̓DŽÉι*ĊіþTų̓ ͑ů’ʆ¼åʢƠ̇̄Ȁ̫сYҤ¼þTЇҕ̫ҹҷoŠĴͩ 9 ͥ _KΑ Šhų̓üɽ̨‘̛̫ȀȃιЇҕΠщ̛ȀЬə̫ҹҷ̨DŽ΀ΙіþTЭ6Ͱ̕ĕΈº̛̫Ȁ̆º̫ʈҤoŠ ·Ҧ̛Ȁ0_Ĵͩ 9 ͥ ų̓ͪ ų̓ӎЈ΀Ι̫ʡǏÉι*ĊǻU_ͮϬ̫KΑ  Cucumber ї˚ϡ̫ϡ$ӌÌƷòBehavior-driven Development, BDD΀Ιn̛ Cucumber ѿɞų̓*À̫ A RSpec үǺ˜Ѝ̺ ї͑ɟƻɽhĈ ě*À̫ͥω ʠǻU_Ĵ ɞ̫M¯Ɋ ƘkʄͥΔʉĊŸƃ˜ćƫ»%¯Ɋ $ git checkout -b sign-in-out 8.1 session hú¥|ň session ɮÿ̞λoŠѓϡɽΤҹ˝ϲĩ̫ŴȀ̞ͦλěѓϡ Rails ̫ɿËĩ*Җ̫܈'ǝћȷǻUƊɮ ¹̛Ůʌų̓“̨DŽ”ї Éι̫ΤΗ ƤϮ̫ session Ō̕ɟƻɽş©͑ þTĴ̛Ȁ–Ҕ˝ϲĩĊ˧Ҧ session 0þTȼp “Ёfǻ”ÞѥʤϽ̛Ȁѥȟˆљwū̶»̛ȀѠ¬Ċ session ȃ_ŗɐ1 Ĵ͈o͘Ʈ ǻUѥȟ n̛ͩ9͑Ō̕ɟƻå̛Ą̏DŽĊ_ˆ'̫Ёf̨DŽ̉Ǚ̶»̛Ȁ˸­“Ѡ¬”҈ȷ*Ċȃ˧Ҧ sessionĴ 8.2.1 ω _KΑ“ˆ'”»ƱɽŐ' Njɯ˼ǻUþTȏ session ϱk ͨć REST ʖʐ̫ЬˬĴ̨DŽҹҷ ¦ō ɞ̫ session̨DŽĊµƶї  sessionѠ¬³_҉ʽ sessionѐ session ě Users ЬˬɽȁĈUsers Ьˬn̛ɕȰƯѫѐ User ʬľȥ '̫ū‡ɕȰή Sessions Ьˬɮ¹̛ cookie ʌū‡ɕȰ̫cookie ɮū‡Ĵ˝ϲĩ ̫ͮÞɘʄų̨̓DŽÉι ŃʄƊɮĴų̓Ń: cookie ̫ӎЈʆ¼Ĵʄωîȷʌ̫ ω ǻU_ʐƶ Sessions ȸ¼ĩµƶ̨DŽϥ Þі_ų̓ȸ¼ĩ ̷–̫ÌkĴ 8.2 ω _ʑŌ̕ cookie ȁҲ̫R̀ 8.1.1 Sessions ¼Ik ̨DŽěѠ¬Éι˜ųɮ̜ Sessions ȸ¼ĩ ̷ư̫ÌkǬ̫̕DŽϥÞĴ new Ìk Ō̕ʄω̫Ź̨DŽ ̫ѐ͘Ɗɮċ create Ìkòѡ POST Иˇ8.1 ωě 8.2 ωѠ¬³ɮċ destroy Ìkòѡ DELETE Иˇ 8.2.6 ωHTTP Иˇě REST Ìk*Җ̫žư–΀þTʙ̺ϥʣ 7.1ӊǻUϬ̚Ǻ Sessions ȸ¼ĩ TîӎЈ΀ΙȁҲ̫үǺ˜Ѝ 1. ûŏ ƤϮ̫ session Ō̕ɟƻɮĴ ŲɩҖ*Ċŗɐї͑ɟƻ̆ºѢćÓďɑdzxǠ̫ΤͤoŠ҆ϡěBɫЦȀ 262 ͩ 8 ͥ ̨DŽěѠ¬ $ rails generate controller Sessions --no-test-framework $ rails generate integration_test authentication_pages ì˽ 7.2 ω ̫“˕ž”ҹҷǻUϬµƶ ̨DŽϥÞ̛ʌ̚Ǻɞ̫ session˕žϥÞ̫ʐǜijŠij 8.1 ȁ͈ “̨DŽ”ҹҷ̫ĵĸ̜ signin_path͙ĊŲ)ϓóě*À ʠǻUϬΠ¢̷ư̫˜ЍŠR̀ 8.1 ȁ ͈þTěR̀ 7.6 ž“˕ž”ҹҷ̫˜Ѝˀч  ij 8.1 ˕žϥÞ̫ʐǜij R̀ 8.1 ž new Ìkěžưϱij̫˜Ѝ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do subject { page } describe "signin page" do 263 before { visit signin_path } it { should have_content('Sign in') } it { should have_title('Sign in') } end end ̓Ĵ˜ЍɮŗХ̫ $ bundle exec rspec spec/ ϬϽR̀ 8.1 ̫˜ЍѫѐӊǻUϬ$ Sessions ЬˬІΦм̜іϬyɌ“̨DŽ”ҹҷ™ĉм̜̫ĉ͖ƃ˜ ɭƂ» Sessions ȸ¼ĩ̫ new Ìkě Users Ьˬ ʠǻUþTn̛ resources ɟ˓ІΦʜ¦̫ REST Ì k resources :sessions, only: [:new, :create, :destroy] ĭ$ǻUˎǐϬɯ͈ǼΠщ sessionȁTǻUžÌk̫͑Ͷ‚5Ҥ¼$ resources ɟ˓ȦŲ5 :only ѥһ üµƶ newcreate ě destroy Ìkɼΐ̫ΔʔÓȠ̨DŽěѠ¬™ĉм̜̫ІΦŠR̀ 8.2 ȁ͈ R̀ 8.2 ІΦ session ̷–̫м̜ config/routes.rb SampleApp::Application.routes.draw do resources :users resources :sessions, only: [:new, :create, :destroy] root to: 'static_pages#home' match '/signup', to: 'users#new', via: 'get' match '/signin', to: 'sessions#new', via: 'get' match '/signout', to: 'sessions#destroy', via: 'delete' . . . end ˕DZІΦѠ¬м̜Ѷϡn̛5 via: 'delete'їìɕȦɪ destroy ÌkϬn̛ DELETE Иˇ R̀ 8.2 ̫м̜ІΦ_̚ǺͶbϥʣ 7.1 ȁ͈̫URI ĵĸěÌk̫žư–΀Šϥʣ 8.1 ȁ͈˕DZǻUyɌ5 ̨DŽěѠ¬™ĉм̜ήµƶ session ̫м̜іɮn̛әϻ~ $5ϽR̀ 8.1 ̫˜ЍѫѐǻUіϬĴ Sessions ȸ¼ĩ ʑ new Ìk̷ư̫R̀ŠR̀ 8.3 ȁ͈Ĉɩ0 Ų)5 create ě destroy Ìk R̀ 8.3 ˎH(Ź̫ Sessions ȸ¼ĩ app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new 264 ͩ 8 ͥ ̨DŽěѠ¬ end def create end def destroy end end ϥʣ 8.1 R̀ 8.2 ̫ІΦ̚Ǻ̫ͨć REST ʖʐ̫м̜–΀ HTTP Иˇ URL ĵĸ ™ĉм̜ Ìk ̴̫ GET /signin signin_path new µƶɞ session ̫ҹҷ̨DŽ POST /sessions sessions_path create µƶ session DELETE /signout signout_path destroy ·Ҧ sessionѠ¬ ȷʌіϬµƶ“̨DŽ”ҹҷ̫ϱijĭ$“̨DŽ”ҹҷ̴̫̫ɮµƶɞ sessionȁTµƶ̫ϱijd: app/views/ sessions/new.html.erbĴϱij ǻUϬɯ͈Τҹ̫ʜӄě  ΈʜŘŠR̀ 8.4 ȁ͈ R̀ 8.4 “̨DŽ”ҹҷ̫ϱij app/views/sessions/new.html.erb <% provide(:title, "Sign in") %>

Sign in

̓ĴR̀ 8.1 ̫˜ЍưВþTѫѐ5ȷʌǻUϬΠ¢̨DŽϥÞ $ bundle exec rspec spec/ 8.1.2 æŀú¥Kħ žˀij 8.1 ěij 7.11 *ĊǻUǫ̀̓DŽϥÞě˕žϥÞŏϯƛŐüɮƅ5Ūʼüɽ Email ĵĸěź ̀Ūʼě˕žϥÞ ʠǻUþTn̛ Capybara ņ¢ϥÞŸ˸­ȧ҄јϡ˜Ѝ Ĵ˜Ѝ̫ѐ͘ ǻUnjċ͘Ʈ ʑ̷ư̫Éιї0ʵɮ TDD Ƣʌ̫şŌ* ǻUʌ˜Ѝņ¢ć ˓ɕǪ̫̇̄DŽѐ͘ʐǜijŠij 8.2 ȁ͈ Mij 8.2 ǻUþT̺¬ŠʔȼB̫ɕȰʵ͆ǻU_ѿɞ˪ʘ“˕ž”ҹҷі_ɯ͈ ҌЕȼ͈˟Ǡї ҌЕȼ͈ɮ Flash ˟ǠǻUþTѫѐҷ̫˜ЍӎЈ it { should have_selector('div.alert.alert-error', text: 'Invalid') } 265 їϡR̀n̛5R̀ 7.32Ĵͩ 7 ̫ͥΌ1  ̛ѐ̫ have_selector ɟ˓have_selector _ʨʙҹҷ ɮč¬̓5ȦŲ̫‹΁oŠ  HTML ʜͭѐĴ Capybara 2.0 ü_ʨʙþϮ̫‹΁ ʄoǻUϬʙȌ̫ ‹΁ɮ div.alert.alert-error ҷїϡR̀_ſȌ  div ʜͭÀҷKΑѐїѾ̫˸ĂRϥ CSS ̫ classìϮ 5.1.2 ωl0Є̎» 5їѾǻUϬʙȌ̫ɮĈɩ™ɽ alert ě alert-error class ̫ div ‹΁ήǻUіʨ˜5ҌЕȼ͈˟Ǡ ɮčÓď5 "Invalid" їЋȁTѝ˜Ѝɮʨ˜ҹҷ ɮčɽҷї‹΁̫
Invalid...
ij 8.2 ˕žŗХҹҷ̫ʐǜij R̀ 8.5 ɮ҂žʜӄě Flash ˟Ǡ̫˜ЍǻUþT̺¬їAR̀Σƅ5 NjѿϬ̫Ѹ¯_Ĵ 8.1.5 ω З ɪ R̀ 8.5 ̨DŽŗХɩ̫˜Ѝ spec/requests/authentication_pages_spec.rb 266 ͩ 8 ͥ ̨DŽěѠ¬ require 'spec_helper' describe "Authentication" do . . . describe "signin" do before { visit signin_path } describe "with invalid information" do before { click_button "Sign in" } it { should have_title('Sign in') } it { should have_selector('div.alert.alert-error', text: 'Invalid') } end end end ˜Ѝ5̨DŽŗХ̫ǧ¥ҷǻUϬ˜Ѝ̨DŽǺÉ̫ǧ¥5ǻUϬ˜Ѝ̨DŽǺÉĊɮčтċ5̛ȀЬəҹҷM ҹҷ̫ʜӄ¸ɜʜӄ ưВÓď̛Ȁ̫ĉŪіϬ˜ЍΤ̫ͤƀτ ɮčɽTõÔ 1. ¬̓5Ȧċ̛ȀЬəҹҷ̫҈ȷ 2. ¬̓5“Ѡ¬”҈ȷ 3. “̨DŽ”҈ȷ˟ŗ5 ž“ІΦSettings”҈ȷ̫˜Ѝ_Ĵ 9.1 ω ų̓ž“ȁɽ̛ȀUsers”҈ȷ̫˜Ѝ_Ĵ 9.3 ω ų̓Š õÔ̫ʐǜijŠij 8.3 ȁ͈2˕DZ“Ѡ¬”ě“GЬə”҈ȷd:“ЦȀAccount”ȚϔÞ Ĵ 8.2.4 ω _KΑŠhѫѐ Bootstrap ų̓ї͑ȚϔÞ ž̨DŽǺÉɩ̫˜ЍŠR̀ 8.6 ȁ͈ R̀ 8.6 ̨DŽǺÉɩ̫˜Ѝ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "signin" do before { visit signin_path } . . . 2. ij́ʌο http://www.flickr.com/photos/hermanusbackpackers/3343254977/ 267 describe "with valid information" do let(:user) { FactoryGirl.create(:user) } before do fill_in "Email", with: user.email.upcase fill_in "Password", with: user.password click_button "Sign in" end it { should have_title(user.name) } it { should have_link('Profile', href: user_path(user)) } it { should have_link('Sign out', href: signout_path) } it { should_not have_link('Sign in', href: signin_path) } end end end ij 8.3 ̨DŽǺÉĊɯ̛͈̫ȀЬəҹҷʐǜij 268 ͩ 8 ͥ ̨DŽěѠ¬ ĴR̀ 8.6 ̛»5 Capybara ȼp̫ have_link ɟ˓Ů̫ͩ ìɕɮ҈ȷɘʄͩ9ìɕɮþѥ̫ :href ȦŲ҈ȷ̫ĵĸĭʶŠ̫R̀ it { should have_link('Profile', href: user_path(user)) } ͆w5ҹҷ ɽ  a ‹΁҈ȷ»ȦŲ̫ URL ĵĸїѾǻUϬʨ˜̫ɮ Ȧċ̛ȀЬəҹҷ̫҈ȷ˕ DZǻUЛ̛ upcase ɟ˓ơ̑Ȁ̫ Email ĵĸтȮǺ5œ¢Džƻ͆wĴɕȰƯ ʙБ̛Ȁɩ̛ȘǏœƄ¢ҕ ӄ 8.1.3 ú¥ĮR ¢Ű˜Ѝ*ĊǻUƊþTµƶ̨DŽϥÞ5ĴR̀ 7.17 ˕žϥÞn̛5 form_for ƣÍ®ɕƫȦŲ˜ì ɕ$ @user õҀ <%= form_for(@user) do |f| %> . . . <% end %> ˕žϥÞę̌DŽϥÞ̫׺Ĵ:͘Ʈ ˎɽ Session ʬľĭʶ0ƊˎɽͶb @user ̫õҀ0ƊɮЗĴʐƶ ̨DŽϥÞɩǻUϬΖ form_for ȼpɹŐ̫xǠ υʌЗŠ̫R̀ form_for(@user) Rails _οÌċ /users ĵĸòѡ POST Иˇž:̨DŽϥÞǻU³Ϭɪ̫͆ȦŲЬˬ̫ĉ͖Tî̷ư̫ URL ĵ ĸ form_for(:session, url: sessions_path) µƶϥÞіɽû ͑ɟ˓̛ form_forή̛ form_tagform_tag 0ɮ Rails ͘ƮƤ̛̫ɟ˓ѐȮ ̛ form_tag *ĊƊě˕žϥÞɽNjŐĈ*Ō5ǻ̓Ĵɮǯn̷̛b̫R̀ʐƶ̨DŽϥÞn̛ form_tag ʐƶ̨DŽϥÞ_̢kΌ1ìϮ 8.5 ω n̛ѝї͑ form_for Džƻì˽R̀ 7.17 ̫˕žϥÞNjŹɫ̫ƊιΠ¢ ͨćij 8.1 ̨̫DŽϥÞŠR ̀ 8.7 ȁ͈ R̀ 8.7 ˕žϥÞ̫R̀ app/views/sessions/new.html.erb <% provide(:title, "Sign in") %>

Sign in

269 <%= form_for(:session, url: sessions_path) do |f| %> <%= f.label :email %> <%= f.text_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.submit "Sign in", class: "btn btn-large btn-primary" %> <% end %>

New user? <%= link_to "Sign up now!", signup_path %>

˕DZ$5ЇŴ̫t¹ǻUіÊ‘5»“˕ž”ҹҷ̫҈ȷR̀ 8.7 ̨̫DŽϥÞɐʔŠij 8.4 ȁ͈ ij 8.4 ̨DŽϥÞ/signup ̛̫Ő5lƊ_Ϋɮʙ̺ Rails ̚Ǻ̫ HTMLl_ےxXȁ̛̫ƣÍ®ɕþTʵ̫͆ŰǺXËѐ̓Ĵ іɮʌ̺ ̨DŽϥÞ̫ HTML ĎŠR̀ 8.8 ȁ͈ R̀ 8.8 R̀ 8.7 ̨DŽϥÞ̚Ǻ̫ HTML 270 ͩ 8 ͥ ̨DŽěѠ¬
lþTžˀ R̀ 8.8 ěR̀ 7.20lþιƝΒ̎»5ȼB̨DŽϥÞĊ_̚Ǻ  params Hash˜ params[:session][:email] ě params[:session][:password] ¯ºžư5 Email ěź̀Ūʼ 8.1.4 BØĮR¾ ěµƶ̛ȀͶbµƶ session ɩϬŌ̕ȼBć˓ɕȰ̫ǧ¥ǻUƝΒΠ¢5žȼBć˓ɕȰ̫˜ЍìϮ R̀ 8.50˦Ê5ɽ©Ōҭ̕ϵcіͯͮÞ̫R̀Ͻ˜Ѝѫѐ5ҷǻUƊʌ¯ʑ ϥÞȼB̫ѐ͘˼ Ċ$̨DŽŗХ˦ÊŗХȼ͈xǠŠij 8.2ɼĊTʶ$Ń̈́ӎЈȼB̫ Email ěź̀Ǭ̕DŽǺÉ̫ǧ¥ ìϮ 8.2 ω ӊǻUʌΠ¢ Sessions ȸ¼ĩ̫ create ÌkŠR̀ 8.9 ȁ͈̓Ĵüɮ̶ȷ˪ʘ̨DŽҹҷĴ˝ϲĩ Ї ҕ /sessions/new˼ĊȼB͝ϥÞɯ͈̫ҹҷŠij 8.5 ȁ͈ R̀ 8.9 Sessions ȸ¼ĩ create Ìk̫¶ţ̂ʄ app/controllers/sessions_controller.rb class SessionsController < ApplicationController . . . def create render 'new' end . . . end 271 ij 8.5 R̀ 8.9 ̫ create Ìkɯ̨͈̫DŽŗХĊ̫ҹҷ OΎ̺ ij 8.5 ɯ͈̫ЛЍxǠl_ò̓ŠĴ 8.1.3 ωʃƍЗѐ̫ϥÞȼBĊ_̚Ǻ params Hash Email ěź̀ѹĴ :session Ҏ --session: email: '' password: '' commit: Sign in action: create controller: sessions ě˕žϥÞͶbїAìɕɮ Ɩŝ̫ HashĴR̀ 4.6 Ϯѐparams Óď5Š̫Ɩŝ Hash { session: { password: "", email: "" } } 0ƊɮЗ params[:session] ʄсƊɮ  Hash 272 ͩ 8 ͥ ̨DŽěѠ¬ { password: "", email: "" } ȁT params[:session][:email] ƊɮȼB̫ Email ĵĸή params[:session][:password] ƊɮȼB̫ź̀ 0ƊɮЗĴ create Ìk params Óď5n̛ Email ěź̀ӎЈ̛ȀсYȁҲ̫’ѸɕȰƬѓ̫ɮǻU ƝΒŲ)5сYӎЈѐ͘ ȁҲ̫ɟ˓å̜ Active Record ȼp̫ User.find_by_emailìϮ 6.1.4 ωTî̜ has_secure_password ȼp̫ authenticate ɟ˓ìϮ 6.3.3 ωǻU*ÀKΑѐŠʔȼ B̫ɕȰć˓authenticate ɟ˓_ѕĬ falseŃ:T̫¯ʑǻUϹ±ȧ˽Š̫ɟƻų̛̓Ą̏DŽ Éι def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) # Sign the user in and redirect to the user's show page. else # Create an error message and re-render the signin form. end end create Ìk̫ͩ ϡn̛ȼB̫ Email ĵĸMɕȰƯ ó¬̷ư̛̫ȀǻUĴ 6.2.5 ωЂѐEmail ĵĸѹ ɮTƄ¢ŪʾDžƻwū̫ȁTїѾЛ̛5 downcase ɟ˓͆wȼBć˓ Email ĵĸĊιʙБ»̷ư̫ЁDŽ ͩ9ϡ̺гʌNjǞcĴ Ruby ΒƤn̛ user && user.authenticate(params[:session][:password]) ϥʣ 8.2 user && user.authenticate(...) þι¬̫̓Δʔ ̛Ȁ ź̀ a && b ūĴ XDZ~ nil && [anything] == false ūĴ ҌЕ̫ź̀ true && false == false ūĴ ʵ̫͆ź̀ true && true == true 273 ǻUn̛ &&Ѯщʨ˜ϓớ̫Ȁɮčć˓ĭ$Ҧ5 nil ě false *ŏ̫ȁɽžПѹϧϱk trueҷ їДúþι¬̫̓ΔʔŠϥʣ 8.2ȁ͈ǻUþTMϥʣ 8.2 ̺¬ǃIǃɕȰƯ ūĴȼB̫ Email ƫȼB 5žư̫ź̀ɩїДúȃ_ѕĬ true 8.1.5 Ðā Flash è« Ĵ 7.3.3 ω ǻUn̛ User ʬľ̫ɕȰӎЈxǠʌɯ͈˕žŗХɩ̫ȼ͈xǠїAҌЕȼ͈xǠɮ–γĴʗ Active Record žП̫ѐї͑ɟƻþT̛Ĵ session ĭ$ session ɮ Active Record ʬľǻUϬѼó̫ ɟ˓ɮĴ̨DŽŗХɩȏҌЕȼ͈xǠЭ~Ζ Flash ˟ǠR̀ 8.10 ɯ͈̫ɮǻUӊʭƉЍų̓ї͑ɟ˓ȁ̛̫ R̀˜ ɽƄƄ̫ҌЕ ij 8.6 ̨DŽŗХĊɯ͈̫ Flash ˟Ǡ R̀ 8.10 ƉЍǬ̕DŽŗХɽƄƄ̫ҌЕ app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end def create user = User.find_by(email: params[:session][:email].downcase) 274 ͩ 8 ͥ ̨DŽěѠ¬ if user && user.authenticate(params[:session][:password]) # Sign the user in and redirect to the user's show page. else flash[:error] = 'Invalid email/password combination' # Not quite right! render 'new' end end def destroy end end ƞƎ ƝΒʑ5ɯ͈ Flash ˟Ǡ̫ƎѸϱijR̀ 7.27ȁTɣҲ˜PyɌѝ Flash ҌЕȼ͈˟ǠƊ_ɯ͈ ¬ʌήĭ$n̛5 BootstrapїҌЕ˟Ǡ̫ʠƻ0NjΨϯŠij 8.6 ѐƊˆR̀ 8.10 ̫˕ѽȁЗїAR̀іɽҕӄɯ͈̫ҹҷ̺гʌNjʵƤģѶ(ҕӄ¬̓ĴĠ‰Ė ҕӄ̫–ҎĴ:Flash ˟ǠĴ Иˇ̫̚ĚėʁɮȥΛūĴ̫ήѿɞ˪ʘҹҷn̛ render ɟ˓ěR ̀ 7.28 ̫тċĈŮͯɞ̫Иˇl_ò̓ї Flash ˟ǠūĴ̫ɩҖˀІǯ̫ϬґNjŐoŠǻUȼB 5ć˓̨̫DŽxǠFlash ˟Ǡ̚Ǻ5˼ĊĴ̨DŽҹҷ ɯ͈¬ʌŠij 8.6їɩŠʔǻU˸­҈ȷт»˜ PҹҷoŠ“ӊҹ”їüͯɮϥÞȼBĊ̫ͩ ʭИˇȁTҹҷ іɮ_ɯ͈ Flash ˟ǠŠij 8.7 ij 8.7 L˼ɯ͈ɽ Flash ˟Ǡ̫ҹҷ 275 Flash ˟ǠˎɽȧӀʁ˟ŗͯɮ͘Ʈ̫  bugĴyʵ*ÀǻUɼşΠ¢ ˜ЍʌȬϓїҌЕ̓Ĵ̨DŽ ŗХɩ̫˜ЍɮþTѫѐ̫ $ bundle exec rspec spec/requests/authentication_pages_spec.rb \ > -e "signin with invalid information" ѐ͘Ʈ ɽҌЕ˜ЍưВɮŗХ̫ȁTǻUϬΠ¢ ιŒȬϓї͑ҌЕ̫˜ЍƬşȬϓї͑ҌЕʵɮ үǺ˜Ѝ̫ȤȂşǹȁ̛̫R̀Š describe "after visiting another page" do before { click_link "Home" } it { should_not have_selector('div.alert.alert-error') } end ȼBć˓̨̫DŽxǠ*Ċї˜Ѝ̛o_˸­Τͤ ̫“ӊҹ”҈ȷʁʀɯ͈̫ҹҷ ˎɽ Flash ҌЕ˟Ǡ ˦Êѝ˜Ѝ̛o̫˜ЍɘVŠR̀ 8.11 ȁ͈ R̀ 8.11 ̨DŽŗХɩ̫ć̕˜Ѝ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "signin" do before { visit signin_path } describe "with invalid information" do before { click_button "Sign in" } it { should have_title('Sign in') } it { should have_selector('div.alert.alert-error', text: 'Invalid') } describe "after visiting another page" do before { click_link "Home" } it { should_not have_selector('div.alert.alert-error') } end end . . . end end 276 ͩ 8 ͥ ̨DŽěѠ¬ ɞ˦Ê̫˜ЍěӀʁ ρɮŗХ̫ $ bundle exec rspec spec/requests/authentication_pages_spec.rb \ > -e "signin with invalid information" ϬϽї˜ЍѫѐǻUϬ̛ flash.now ɻȮ flashflash.now ƊɮҒ̛ʌĴѿɞ˪ʘ̫ҹҷ ɯ͈ Flash ˟Ǡ̫Ĵòѡɞ̫Иˇ*ĊFlash ˟Ǡt_˟ŗʵ̫͆ create ÌkR̀ŠR̀ 8.12 ȁ͈ R̀ 8.12 Ǭ̕DŽŗХȁҲ̫ʵ͆R̀ app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) # Sign the user in and redirect to the user's show page. else flash.now[:error] = 'Invalid email/password combination' render 'new' end end def destroy end end ̓Ĵ̨DŽŗХɩ̫ȁɽ˜ЍưВѹþTѫѐ5 $ bundle exec rspec spec/requests/authentication pages spec.rb \ > -e "with invalid information" 8.2 ú¥¬K  ωŌ̕5̨DŽŗХ̫ǧ¥ї ωǻUϬǬ̕DŽǺÉ̫ǧ¥5ų̛̓Ą̏DŽ̫ѐ͘ɮʄ2̴À$ʴɼάӎ Ruby Π͘ιÇ̫Ѹ¯lϬļȥЙŰʄω‚şǏ̕¦ōQ¬œҀ̫λÇÐÌƬşͩ ʷіͯɮͮÞ̫Ű Ǻ Sessions ȸ¼ĩ̫ create ÌkˎH(ҭ̫ѐіɮҲϬ ˸ƄȎƚ ǻUҲϬȏR̀ 8.12 Ǭ̕DŽǺɯɊ ̫˕ѽȮǺ™g̫R̀n̛ sign_in ɟ˓ų̨̓DŽɈk˼Ċтċ ̛Ȁ̫ЬəҹҷŠR̀ 8.13 ȁ͈їƊɮǻUn̛̫Ȏƚn̛іˎŲ)̫ɟ˓ sign_inʄωĊҷ̫Ź_ Ų)їɟ˓ R̀ 8.13 Űɗ̫ create ÌkR̀іιʵƤn̛ 277 app/controllers/sessions_controller.rb class SessionsController < ApplicationController . . . def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) sign_in user redirect_to user else flash.now[:error] = 'Invalid email/password combination' render 'new' end end . . . end 8.2.1 “Ļ+­” ̓ĴǻUϬƷţų̨̓DŽÉι5ͩ ʷɮų̓“Ёfǻ”їÉιå̛Ą̏DŽ̫̉Ǚ_ϧ“ˆљ”Ёf̶»̛Ȁ ˸­“Ѡ¬”҈ȷ$ʴų̨̓DŽÉι̛»̫®ɕƝΒде5`Ι̫ MVC ʖʐ˜ A®ɕϬĈɩĴȸ¼ĩěϱ ij n̛Ĵ4.2.5 ω KΑѐRuby ɊȥʬĻmoduleÉιȄÓ ΀²®ɕĴĈ̫ĵɟƼ‘ǻU_¹ ̛ʬĻʌȄỚȀсYӎЈ̷–̫®ɕǻUǃ˼þTµƶ ɞ̫ʬĻѐ Sessions ȸ¼ĩƝΒȼp5 ĉ $ SessionsHelper ̫ʬĻήїʬĻ ̫ƣÍɟ˓_οÌƼ‘ Rails ͘Ʈ̫ϱij ȁTǻUƊ̶ȷn ̛ї̓Ǻ̫ʬĻ˼ĊĴ Application ȸ¼ĩ Ƽ‘ŠR̀ 8.14 ȁ͈ R̀ 8.14 Ĵ Application ȸ¼ĩ Ƽ‘ Sessions ȸ¼ĩ̫ƣÍɟ˓ʬĻ app/controllers/application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery with: :exception include SessionsHelper end әϻǧ¥ƣÍ®ɕüþTĴϱij n̛ιĴȸ¼ĩ n̛ήǻUҲϬĈɩĴȸ¼ĩěϱij n̛ƣÍ® ɕȁTǻUƊȂÌƼ‘ƣÍ®ɕȁĴ̫ʬĻ ĭ$ HTTP ɮɣ̉Ǚ̫ÝϿȁTŠʔư̛͘ƮҲϬų̨̓DŽÉι̫ЏƊϬȌ» ͑ɟ˓Ёf̛Ȁ̫̉ǙΜȥ ̛Ą̏DŽ̉Ǚ̫ɟ˓* ɮn̛Ƥϰ̫ Rails sessionѫѐ session ®ɕơ̑Ȁ̫ id wūĴ“ЁǑʈʜ remember token” session[:remember_token] = user.id 278 ͩ 8 ͥ ̨DŽěѠ¬ session žПơ̑Ȁ id wūĴ˝ϲĩ̫ cookie їʠĴΤ̫ͤȁɽҹҷƊѹþTn̛5˝ϲĩ–ҔĊ cookie 0ҩ*ŗɐĴΤͤ ̫XhҹҷüҲЛ̛ User.find(session[:remember_token]) ƊþTóĬ̛ ȀžП5Rails ĴŌ̕ session ɩ_͆wů’ǝ{ϋ̛Ȁ[ijaѭ̛Ȁ idRails þTѫѐʿ session ̫ session id ʨ˜» ʢȰ͈o͘Ʈ̫ІϹ̴ʜǻUϹ±Ϭų̫̓ɮȥ'wū̫ sessionån˝ϲĩ–Ҕ5̨DŽ̉ǙqɧūĴȁ T̨‘̛̫ȀϬɽ ȥ'wū̫ʜЉͨȃϡ$ʶǻUϬ$ʿ̛Ȁ̚Ǻ ġ ήů’̫ЁǑʈʜґʁ ū‡_ҩ̽˝ϲĩ̫–Ҕή˟ŗ ЁǑʈʜϬҟƓ»̆Ų̛̫ȀžПήϬwūгʌTNJĊ̛ȁTǻUƊþTȏŮІ$ User ʬľ̫ƓǝŠij 8.8ǻUʌΠ¢ User ʬľ̫˜ЍŠR̀ 8.15 ȁ͈ ij 8.8 User ʬľ˦Ê5 remember_token Ɠǝ R̀ 8.15 ЁǑʈʜ̫ͩ ˜Ѝ spec/models/user_spec.rb require 'spec_helper' describe User do . . . it { should respond_to(:password_confirmation) } it { should respond_to(:remember_token) } it { should respond_to(:authenticate) } . . . end ϬϽї˜ЍѫѐǻUϬ̚ǺЁǑʈʜƓǝȆϡŠĚS $ rails generate migration add_remember_token_to_users ˼Ċȧ˽R̀ 8.16 yɌ̚Ǻ̫ю͗ɘV˕DZĭ$ǻUϬn̛ЁǑʈʜóĬ̛ȀȁTǻU$ remember_token ²Ê5΂ƼìϮ ɡ˕ 6.2 R̀ 8.16 users ϥ˦Ê remember_token ²̫ю͗ db/migrate/[timestamp]_add_remember_token_to_users.rb 279 class AddRememberTokenToUsers < ActiveRecord::Migration def change add_column :users, :remember_token, :string add_index :users, :remember_token end end ˼ĊіϬɹɞ“ƷòɕȰƯ”ě“˜ЍɕȰƯ” $ bundle exec rake db:migrate $ bundle exec rake test:prepare ̓ĴUser ʬľ̫˜ЍưВþTѫѐ5 $ bundle exec rspec spec/models/user_spec.rb ȷʌǻUϬάϛЁǑʈʜϬwūH(ɕȰїɽNjŐ͑ѥȟ˜ųXhзŒґ̫ҩʆŪͨ"ѹɮþT̫üϬι wЈġ ǝRuby ʜ¦Ư SecureRandom ʬĻȼp̫ urlsafe_base64 ɟ˓þT˯зǻU̫Ϭˇ3 SecureRandom.urlsafe_base64 µƶ̫Ūͨ"ґƴ$ 16̜ A-Za-z0-9±΋_ěћŪͨ-΍Ǻ ʿ dŪͨѹɽ 64 ͑þι̫ǧ¥ȁTý‚“base64”.ȁTЁǑʈʜ̷̫ͪʫ̐Ɗɮ 1/6416 = 2-96 ≈ 10-29 ےþTỤ̈́ ǻUϹ±Ĵ˝ϲĩ ū‡ї base64 ʈʜĴɕȰƯ ū‡ÊźĊ̫̂ʄŠʔϬοĮ̀‘̛ȀƊþTM cookie ó¬ЁǑʈʜÊźĊʙБɕȰƯɕȰƯ*ȁTüwūÊźĊ̫ʈʜɮĭ$åtɗɕȰƯѹ˒ҳ5ɍ­ έ0ɣ˓n̛ЁǑʈʜ̨‘Τͤ$5ϽЁǑʈʜɹů’ǻUϹ±ʿʭĬЏѹ̚Ǻ ʠ̫ʈʜїʠånĬЏ ϧÎȥ5ɍ­έ†ó cookie aϪǺʗ̛Ą̏DŽ̛Ȁʭ̨DŽɩÀ ĬЏƊ_ŗɐ_ЏÎȥþTѫѐ Firesheep ȇƒʨ˜n̛їȇƒþT̺»NjŐϖĉ̫ΤͤĴћȷ»“• WIFI ɩЁǑʈʜѹɮþϮ̫$5ѵ їҕӄþT’ͤn̛ SSLĴ 7.4.4 ωɽKΑ ̻ų̫ư̛͘Ʈѹ_οĮ̀‘´˕ž̛̫Ȁїʠ‚̫ Åk̛Ɗɮµƶ5 ɞ̫ЁǑʈʜcɮǻUǯ ї(‚ǻUϬ̛ ͑ɹş̫ɟƻ͆wM Ʒţ̛ȀƊɽþ̛̫ЁǑʈʜ$ʶǻUϬn̛ĬЛ®ɕ̚Ǻʈ ʜĴ 6.2.5 ω ͆w Email ġ ǝɩ̛ѐĬЛ®ɕЛ̛̫ɮ before_save̓ĴǻUϬЛ̛ before_create Ĵµƶ̛ȀɩІΦЁǑʈʜ4 Ϭ˜Ѝїѐ͘ǻUþTwū˜ЍȁҲ̛̫ȀžП˼Ċʨʙ remember_token ɮč$ҵ͝~їʠ‚Š ʔTĊҲϬɌõЁǑʈʜ̫̚Ǻɟƻ0ɣҲyɌ˜Ѝ˜ЍR̀ŠR̀ 8.17 ȁ͈ R̀ 8.17 ˜Ѝć˓̫ҵ͝ЁǑʈʜ~ spec/models/user_spec.rb require 'spec_helper' describe User do 3. ǻѥȟї(̚ǺЁǑʈʜɮĭ$̺5 Railscasts ͩ 274 үRemember Me & Reset Password 4. Active Record Ɋȥ̫˜PĬЛ®ɕĴ Rails Ȧß ɽKΑ 280 ͩ 8 ͥ ̨DŽěѠ¬ before do @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end subject { @user } . . . describe "remember token" do before { @user.save } its(:remember_token) { should_not be_blank } end end R̀ 8.17 ̛»5 its ɟ˓Ůě it Njˆѐ˜ЍžПɮìɕ ȦŲ̫Ɠǝήɮɗ˜Ѝ̫žП0Ɗɮ ЗŠ̫R̀ its(:remember_token) { should_not be_blank } ͪĈ: it { expect(@user.remember_token).not_to be_blank } ͘ƮȁҲ̫R̀_ˠî» Aɞ̫̾Љ˜ ǻU˦Ê5 ĬЛ®ɕʌ̚ǺЁǑʈʜ before_create :create_remember_token ҷїϡR̀ý‚“ɟ˓Ƽ̛”ǃ Rails Ȇϡ»їϡR̀ɩ_ſȌ ĉ$ create_remember_token ̫ɟ ˓Ĵµƶ̛Ȁ*ÀȆϡĴR̀ 6.20 ǻU̶ȷΖ before_save ȦŲ5Ļìɕcɹȹϐn̛ї͑“ɟ˓ Ƽ̛”ɟƻήcreate_remember_token ü_Ĵ User ʬľѸn̛ȁTˎǐϬȏŮƷɎΖ̛Ȁ*ŏ̫ žПŠ 7.3.2 ω ȁЂĴ Ruby ǻUþTn̛ private –ҎŪ5Ҥ¼ɟ˓̫þϮǝ pivate def create_remember_token # Create the token. end ĴͶ private *ĊŲ)̫ɟ˓ѹ_ϧІ$͐ɽɟ˓ȁTŠʔȆϡҷ̫Ɉk $ rails console >> User.first.create_remember_token 5. Ќέ˕ ˜ų private ɮɟ˓ήɮ–ҎŪИìҘRuby Π͘ДϷP233 281 Ɗ_Ȓ¬ NoMethodError ƸƤ Ĵ create_remember_token ɟ˓ ϬΖ̛Ȁ̫ƓǝЭ~ҲϬĴ remember_token ÀÊ self –ҎŪ def User.new_remember_token SecureRandom.urlsafe_base64 end def User.encrypt(token) Digest::SHA1.hexdigest(token.to_s) end private def create_remember_token self.remember_token = User.encrypt(User.new_remember_token) end Active Record ɮȏʬľ̫ƓǝěɕȰƯϥ ̫²žư̫ŠʔȦŲ self ̫ЏǻUƊüɮµƶ5 ĉ$ remember_token ̫ƎѸõҀήƝїþɮǻUʁʀnj»̫ΔʔÊ self *ĊЭ~ɈkƊ_ȏ~Э~Ζ ̛Ȁ̫ remember_token Ɠǝwư̄Ȁɩҩ̽˜P̫Ɠǝ гū‘ɕȰƯ̓Ĵl̾ѱ5$H(R̀ 6.20 ̫ before_save $H(Ϭ̛ self.name ή̶ȷ̛ email ˕DZǻUn̛ SHA1 Êź5ЁǑʈʜї͑ĝơͯ˓ˀ 6.3.1 ω ̛ʌÊź̛Ȁź̫̀ Bcrypt ѬƴǕnjŐ*ȁ T̺ Ѭƴɮĭ$ž̨‘̛̫ȀʌЗʿҹҷѹ_ÊźЁǑʈʜìÊ8.2.2 ωSHA1 ̫ů’ǝŠ Bcryptcι˯з̓Ĵ̫ҲˇÊźĊ̫ЁǑʈʜɮ 16 dҩʆŪͨŃʄɣ˓͂ϵѝR̀*ȁTЛ̛ to_sɮ$5Ō̕ъ‘$ nil ̫ǧ¥ž˼Ĵ˝ϲĩ _ѯ»»˜Ѝɩ…Ɔ_¬̓ encrypt ě new_remember_token ɟ˓Ų)Ĵ User Ͷ ĭ$9έɣҲ̛ȀųoƊþn̛ήіɮ“Ʒɟ ˓d: private ҷĴ 8.2.3 ω _ƃїɟ˓Á͎¬ User ʬľ ȏѝ̫¯ʑΔćгʌɼΐnj»̫ User ʬľɘVŠR̀ 8.18 ȁ͈ R̀ 8.18 ̚ǺЁǑʈʜ̫ before_save ĬЛ®ɕ app/models/user.rb class User < ActiveRecord::Base before_save { self.email = email.downcase } before_create :create_remember_token . . . def User.new_remember_token SecureRandom.urlsafe_base64 end def User.encrypt(token) 282 ͩ 8 ͥ ̨DŽěѠ¬ Digest::SHA1.hexdigest(token.to_s) end private def create_remember_token self.remember_token = User.encrypt(User.new_remember_token) end end ҼtЗ ǻU$ create_remember_token ɟ˓ňÊ5 Ə΢јїʠþTɹş̫͟¬їAɟ˓ɮĴ private *ĊŲ)̫Βӎϥɪїʠ‚ɮɪɴĵ6 ĭ$ÊźĊ̫ SecureRandom.urlsafe_base64 ɟ˓µƶ̫Ūͨ"þι$͝~ȁTž User ʬľ̫˜Ѝ̓Ĵ ưВþTѫѐ5 $ bundle exec rspec spec/models/user_spec.rb 8.2.2 † sign_in Ìä ʄƄωǻUϬƷţų̨̓DŽÉι5ӊʌŲ) sign_in ɟ˓ ƄωƝΒЗɪ5ǻUϹ±ų̫̓сYӎЈ ɟƻɮĴ̛Ȁ̫˝ϲĩ ū‡ЁǑʈʜĴΤ̫ͤҹҷҹҷ*ҖѫѐїЁǑʈʜϓóɕȰƯ ̛̫ȀЁDŽ _Ĵ 8.2.3 ωų̓ų̓ї ІǯȁҲ̫R̀ŠR̀ 8.19 ȁ͈їʼR̀n̛5 current_user ɟ˓_Ĵ 8.2.3 ω Ų) R̀ 8.19 ŰɗcіιʵƤn̛̫ sign_in ɟ˓ app/helpers/sessions_helper.rb module SessionsHelper def sign_in(user) remember_token = User.new_remember_token cookies.permanent[:remember_token] = remember_token user.update_attribute(:remember_token, User.encrypt(remember_token)) self.current_user = user end end ѝR̀΍Ȍ5ІŲ̫ʷӏ ӊµƶɞʈʜ ҩĊȏʂÊź̫ʈʜū‘˝ϲĩ̫ cookie ˼ĊȏÊźĊ̫ ʈʜū‘ɕȰƯ ɼĊȏ¼Ų̛̫ȀІ$ǃĄ̀‘̛̫Ȁ˕DZwūЁǑʈʜn̛̫ɮ update_attribute ɟ˓їʠþTнѐɕȰӎЈɹɞÞƓǝǻUǐҽ̛їɟ˓ĭ$ǻUɣ˓ȼp̛Ȁ̫ź̀îź̀͆ϻ 6. Ќέ˕ Šʔȧ˽ bbatsov ̫Ruby Π͘ӈʣȦßʌΠ¢ Ruby R̫̀ЏƊˎǐϬŐÊ Ə΢ј 283 R̀ 8.19 ̛»̫ cookies ɟ˓ɮ̜ Rails ȼp̫ǻUþTȏŮ̺Ǻ Hash˜ ʿ‹΁íѹɮ  HashÓ ď‹΁value ȦŲ cookie ̫ɘʄexpires ȦŲ cookie ̫ŗɐɥʁoŠǻUþTn̛ѝR̀ų̨̓ DŽÉιȏ cookie ̫~І$̛Ȁ̫ЁǑʈʜŗɐɥʁІ$ 20 ƪ*Ċ cookies[:remember_token] = { value: remember_token, expires: 20.years.from_now.utc } їѾn̛5 Rails ȼp̫ɩҖƣÍɟ˓ГǧìϮɡ˕ 8.1 Íå 8.1cookie o 20.years.from_now c|Æ Ĵ 4.4.2 ω KΑѐlþTċXh̫ Ruby Ͷ̙πɮΦ̫Ͷ ˦ÊοŲ)̫ɟ˓ǻUƊċ String Ͷ˦ Ê5 palindrome? ɟ˓ήіò̓5 "deified" ɮĬɘǻUіKΑѐRails $ Object Ͷ˦Ê5 blank? ɟ˓ȁT"".blank?" ".blank? ě nil.blank? ̫ѕĬ~ѹɮ trueR̀ 8.19 Ō̕ cookie ̫R̀íɮ on̛5 Rails ȼp̫ɩҖƣÍɟ˓їAɟ˓ɮ˦Ê» Fixnum ͶɕŪ̫ŃͶ ̫ $ rails console >> 1.year.from_now => Sun, 13 Mar 2011 03:38:55 UTC +00:00 >> 10.weeks.ago => Sat, 02 Jan 2010 03:39:14 UTC +00:00 Rails і˦Ê5˜P̫ƣÍ®ɕŠ >> 1.kilobyte => 1024 >> 5.megabytes => 5242880 ї©ƣÍ®ɕþ̛:Ҥ¼`ɘV̫œƄoŠij́ɼœдѐ 5.megabytes ї͑$ΦͶ˦Êɟ˓̫̆ǝNj˶tþTȇƒ Ruby ̫Éιѐn̛ɩϬƄǏ A˜ų Rails ̫NjŐ^Ү *ŌʵƻŃ: Ruby ДϷ̫ї ̆ǝ ĭ$ƷòέΒƤϬȏ cookie ̫ŗɐɥʁІ$ 20 ƪĊȁT Rails ̆ºȼp5 permanent ɟ˓ÀҷŌ̕ cookie ̫ R̀þTɌ¢Ǻ cookies.permanent[:remember_token] = remember_token Rails ̫ permanent ɟ˓_οÌȏ cookie ̫ŗɐɥʁІ$ 20 ƪĊ ІŲ5 cookie *ĊĴΤҹ ǻUƊþTn̛ҷ̫R̀óĬ̛Ȁ 284 ͩ 8 ͥ ̨DŽěѠ¬ User.find_by(remember_token: remember_token) ˜ų˝ϲĩ wū̫ cookie ƫɮ HashЭ~Ζ cookies üɮȏ~Tɘʄ̫DžƻwūĴ˝ϲĩ їʵg̓5 Rails ̫ɴιǻUɣҲ–Ǐ™g̫Ō̕Ύω˕ĵų̓ư̛͘Ʈ̫Éι 8.2.3 ĬZ¤Jö®  ƄωƝΒKΑ5ŠhĴ cookie ū‡ЁǑʈʜTNJĊ̛ї ƄωǻUϬ̺ ŠhóĬ̛ȀǻUĬҾ  sign_in ɟ˓ module SessionsHelper def sign_in(user) remember_token = User.new_remember_token cookies.permanent[:remember_token] = remember_token user.update_attribute(:remember_token, User.encrypt(remember_token)) self.current_user = user end end ̓Ĵіɣ˓n̛̫R̀ɮ self.current_user = user їϡR̀µƶ5 current_user ɟ˓þTĴȸ¼ĩěϱij n̛ȁTlɤþTїʠ̛ <%= current_user.name %> 0þTїʠ̛ redirect_to current_user їϡR̀ ̫ self 0ɮǐҽ̫êĭĴ¯ʑR̀ 8.18 ɩƝΒЗѐŠʔˎɽ selfRuby üɮŲ)5 ĉ$ current_user ̫ƎѸõҀ ĴƷţΠ¢ current_user ɟ˓̫R̀*ÀИOΎ̺їϡR̀ self.current_user = user їɮ Э~ɈkǻUǐҽŲ)̷ư̫ɟ˓ȃιї(̛Ruby $ї͑Э~Ɉkȼp5 ͑̆º̫Ų)ɟƻŠ R̀ 8.20 ȁ͈ R̀ 8.20 ų̓ current_user ɟ˓žư̫Э~Ɉk app/helpers/sessions_helper.rb 285 module SessionsHelper def sign_in(user) . . . end def current_user=(user) @current_user = user end end їʼR̺̀гʌNjŚǞĭ$œŐɕ̫Π͘ДϷƫŠЄĴɟ˓ĉ n̛ͪĂ˜ųїʼR̀Ų)̫ current_user= ɟ˓ɮ̛ʌŌ̕ current_user Э~Ɉk̫0ƊɮЗŠ̫R̀ self.current_user = ... _οÌтȮǺҷї͑Džƻ current_user=(...) Ɗɮ̶ȷЛ̛ current_user= ɟ˓ȷô̫ìɕɮЭ~Дúār̫~ʄo ɮϬ̨DŽ̛̫ȀžП current_user= ɟ˓Ų)güɽ ϡR̀åІŲųoõҀ @current_user ̫~TōĊ̛ ĴƤϮ̫ Ruby R̀ ǻUі_Ų) current_user ɟ˓̛ʌЙó @current_user ̫~ŠR̀ 8.21 ȁ ͈ R̀ 8.21 ƉЍŲ) current_user ɟ˓ѐǻU_n̛ї͑ɟƻ module SessionsHelper def sign_in(user) . . . end def current_user=(user) @current_user = user end def current_user @current_user # Useless! Don't use this line. end end 286 ͩ 8 ͥ ̨DŽěѠ¬ ҷ̫‚˓˜ųƊɮų̓5 attr_accessor ɟ˓̫Éι4.4.5 ωKΑѐ7Šʔȧ˽R̀ 8.21 ʌŲ) current_user ɟ˓_¬̓ ҕӄ ͘Ʈ_Ёf̛Ą̫̏DŽ̉Ǚ ɦ̛Ȁт»˜P̫ҹҷsession Ɗŗ ɐ5_οÌѠ¬ϋϬѵїҕӄǻUϬn̛R̀ 8.19 ̚Ǻ̫ЁǑʈʜʙƠ̏ȀŠR̀ 8.22 ȁ͈˕ DZĭ$ɕȰƯ wū̫ЁǑʈʜɮÊź̫ȁTĴ̛ʌʙƠ̏Ȁ*ÀϬÊźM cookie Йó̫ʈʜǻUþTn ̛R̀ 8.18 Ų)̫ User.encrypt ɟ˓Êź R̀ 8.22 ѫѐЁǑʈʜʙȌǃÀ̛Ȁ app/helpers/sessions_helper.rb module SessionsHelper . . . def current_user=(user) @current_user = user end def current_user remember_token = User.encrypt(cookies[:remember_token]) @current_user ||= User.find_by(remember_token: remember_token) end end R̀ 8.22 n̛5 ƤϮcɮNjŹɫ̕ϵ̫ ||=“or equals”Ɉkͨɡ˕ 8.2 ɽГΎKΑn̛їɈ kͨ*ĊǃIǃ @current_user ʂŲ)ɩȃ_ȏѫѐЁǑʈʜϓớ̫ȀЭ~ΖųoõҀ @current_user80ƊɮЗŠ̫R̀ @current_user ||= User.find_by(remember_token: remember_token) üĴͩ ʭЛ̛ current_user ɟ˓ɩЛ̛ find_by ɟ˓ŠʔĊ˟Л̛̫ЏƊ̶ȷѕĬ @current_user ̫~ήǐŸʙБɕȰƯ9ї͑ɟƻ̫^˸üɽǃĴ Иˇ ŐʭЛ̛ current_user ɟ˓ɩȃιɯ̓ ͰǚʠüϬ̛ȀЇҕ5̷ư̫ҹҷfind_by ɟ˓ѹπƅ_Ȇϡ ʭ Íå 8.2||= Â,ĈČ ||= ɈkͨҵƤιŒg̓ Ruby ̫̆ǝŠʔlȄͯґʁјϡ Ruby Π̫͘ЏƊϬşşŭ1Ư̫̊˓¶ŭɩ_ ϳnj ||= Nj͔͋ѐѫѐě˜PɈkͨͶˀ*Ċl_ò̓0ɮNjҭ̕ϵ ǻUʌ̺ ɌõƝΒŲ)̫õҀɩΒƤn̛̫ΔʐĴNjŐ͘Ʈ ѹ_ȏõҀοň Šȁ͈ x=x+1 7. ˜ųї͑ɟƻɮےͪɐ̫attr_accessor _ο̵ƶó~ěІŲɟ˓ 8. υʌЗїúЏ̫DZǜɮȏ¶ţ~$ nil ̫õҀҟ5ɞ~ѐ ||= 0_ȏ¶ţ~$ false ̫õҀҟɞ~ 9. ї0ɮ ͑ōǓmemoizationГǧìϮɡ˕ 6.3 287 œŐɕДϷѹ$ї͑Ɉkȼp5ͮÔ̫ɈkͨĴ Ruby þTȧ˽ҷ̫ɟƻѿ¢CC++Perl PythonJava ͪ0Šʶ x += 1 ˜PɈkͨ0ɽͶb̫ͮÔDžƻ $ rails console >> x = 1 => 1 >> x += 1 => 2 >> x *= 3 => 6 >> x -= 7 => -1 ҷ̫&oþTʫȠ$x = x O y ě x O=y ɮͪɐ̫˜ O ϥ͈Ɉkͨ Ĵ Ruby іΒƤ_ѯ»ї͑ǧ¥ŠʔõҀ̫~$ nil ³Э6˜P̫~č³ƊɌõїõҀ̫~4.2.3 ω KΑѐ || ǼɈkͨȁTї͑ǧ¥þT̛Š̫R̀ϥ͈ >> @user => nil >> @user = @user || "the user" => "the user" >> @user = @user || "another user" => "the user" ĭ$ nil ϥ͈̫ƞƆ~ɮ falseȁTͩ Э~ɈkͪĈ: nil || "the user"їДú̫ϹͯΔʔ ɮ "the user" Ͷb̫ͩ9Э~ɈkͪĈ: "the user" || "another user"їДú̫ϹͯΔ ʔіɮ "the user"ĭ$ "the user" ϥ͈̫ƞƆ~ɮ trueїǼɈkĴȆϡ5ͩ ϥэƻ*ĊƊΐ ʴ5ǼɈk̫ȆϡҼƮɮMƙπāüϬ¬̻̓~Ɗ_ΐʴДú̫Ȇϡї͑ɟƻ͖k“̿мϹͯshortcircuit evaluation” ěҷ̫ȸ¼ÿ_Џžˀ*ĊǻUþTò̓ @user = @user || value ͨć x = x O y ̫DžƻüҲ ȏ O ȮǺ ||ȁTƊnj»5ҷї͑ͮ¢Džƻ >> @user ||= "the user" => "the user" ҭ̕ϵĎ10 288 ͩ 8 ͥ ̨DŽěѠ¬ 8.2.4 Å[‹īť» ʄƄωǻUϬŰǺ̫ɮų̨̓DŽѠ¬Éι̫ɼĊ ʷʢǪ̇̄DŽ̉ǙɌõƞƎ ̫ƀτ҈ȷŠij 8.3 ȁ͈ǻ UϬĴ̨DŽěѠ¬Ċɯ͈Ĉ̫ƀτϬ˦ÊȦċ²¬ȁɽ̛Ȁҹҷ̫҈ȷ»̛ȀІΦҹҷ̫҈ȷͩ 9 ͥÊ ‘іɽ»ǃĄ̀DŽ̛ȀЬəҹҷ̫҈ȷʑїA҈ȷ*ĊR̀ 8.6 ̫˜ЍƊþTѫѐ5їɮʄ̴ͥÀ $ʴ˜ЍӊʭõΝѫѐ ĴΤ̫ͤƞƎ Ɍõƀτ҈ȷҲϬ̛» ERb ̫ if-else ¯ɊΔʐ <% if signed_in? %> # Links for signed-in users <% else %> # Links for non-signed-in-users <% end %> ϋϬѝR̀гk̛Ϭ̛ signed_in? ɟ˓ǻU̓ĴƊʌŲ) Šʔ session ūɽǃÀ̛Ȁ̫ЏƊþTЗ̛ȀƝΒ̨DŽ5ǻUϬ¸ɜ current_user ̫~ɮɮ nilїѾ ҲϬ̛»óñɈk̛ͨdzĄĂ ! ϥ͈ υЙk“bang”üϬ current_user ̫~ɮ nilƊЗɪ̛Ą̏DŽ 5ŠR̀ 8.23 ȁ͈ R̀ 8.23 Ų) signed_in? ƣÍɟ˓ app/helpers/sessions_helper.rb module SessionsHelper def sign_in(user) remember_token = User.new_remember_token cookies.permanent[:remember_token] = remember_token user.update_attribute(:remember_token, User.encrypt(remember_token)) self.current_user = user end def signed_in? !current_user.nil? end . . . end Ų)5 signed_in? ɟ˓ĊƊþT̽ȂyɌƞƎ ̫ƀτ5ǻUϬ˦Êīɞ҈ȷ˜ ҈ȷ̫ĵĸ ņͩ 9 ͥŸņ 10. Ќέ˕ їѾž ||= ̫¯ʑě Peter Cooper ̫¯ʑɽ˸ƛƸǻȹϐl̺T Ruby Inside ̫What Ruby’s ||= (Double Pipe / Or Equals) Really Does ɘ 289 <%= link_to "Users", '#' %> <%= link_to "Settings", '#' %> Ѡ¬҈ȷ̫ĵĸn̛R̀ 8.2 Ų)̫ signout_path <%= link_to "Sign out", signout_path, method: "delete" %> ˕DZǻUі$Ѡ¬҈ȷȦŲ5Ͷľ$ Hash ̫ìɕȦɪ˸­҈ȷĊòѡ̫ɮ HTTP DELETE Иˇ11ɼĊ ǻUіϬ˦Ê »Ьəҹҷ̫҈ȷ <%= link_to "Profile", current_user %> ї҈ȷǻUʄþT¢Ǻ <%= link_to "Profile", user_path(current_user) %> ѐǻUþT̶ȷȏ҈ȷĵĸІ$ current_userRails _οÌƃ˜тȮǺ user_path(current_user) Ĵ˦Êƀτ҈ȷ̫ѐ͘ ǻUіϬn̛ Bootstrap ų̓ȚϔÞ̫ɐʔ™g̫ų̓ɟƻþTìҘ Bootstrap ̫ɘ ʦ˦Êƀτ҈ȷȁҲ̫R̀ŠR̀ 8.24 ȁ͈˕DZ˜ ě Bootstrap ȚϔÞɽ–̫ CSS id ě class R̀ 8.24 ʢǪ̇̄DŽ̉ǙɌõƀτ҈ȷ app/views/layouts/_header.html.erb ų̓ȚϔÞіϬ̛» Bootstrap ̫ JavaScript R̀ǻUþTΠщư̛͘Ʈ̫ JavaScript ɘVѫѐ asset pipeline Ƽ‘ȁҲ̫ɘVŠR̀ 8.25 ȁ͈ ij 8.9 ̨DŽĊɯ͈5ɞ҈ȷěȚϔÞ R̀ 8.25 ȏ Bootstrap ̫ JavaScript R̀ʑ application.js app/assets/javascripts/application.js //= require jquery //= require jquery_ujs //= require bootstrap 291 //= require turbolinks //= require_tree . Ƽ‘ɘV̫Éιɮ̜ Sprockets ų̫̓ήɘVʄсɮ̜ 5.1.2 ω ˦Ê̫ bootstrap-sass gem ȼp̫ ˦Ê5R̀ 8.24 *Ċȁɽ̫˜ЍưВѹþTѫѐ5 $ bundle exec rspec spec/ ̓Ĵ̨‘̛̫ȀƊþT̺»R̀ 8.24 ɞ˦Ê̫҈ȷěȚϔÞ5Šij 8.9 ȁ͈ ̓ĴlþTӎЈ ɮčþT̨DŽ˼Ċ–Ҕ˝ϲĩŸȄƷ̺ ɮčіɮ̨‘̫̉ǙŠʔҲϬlіþT̶ ȷʙ̺˝ϲĩ̫ cookiesŠij 8.10 ȁ͈ ij 8.10 ʙ̺˝ϲĩ ̫ЁǑʈʜ cookie 8.2.5 å>cý»ú¥ ϝ˼̓ĴŃʄŰǺ5̛ȀсYӎЈÉιcɮɞ˕ž̛̫Ȁþιіɮ_įǩ$H(˕žĊˎɽ̨DŽĖĴų̓Ѡ ¬Éι*ÀǻUіϬų̓˕žĊ̶ȷ̨DŽ̫ÉιǻUϬΠ¢˜ЍĴсYӎЈ̫˜Ѝ ʑ ϡR̀ŠR ̀ 8.26 ȁ͈їʼR̀Ϭ̛»ͩ 7 ͥ Ό1 ̫“after saving the user” describe ĻìϮR̀ 7.32Šʔ* Àlˎɽ‚їΌ1̫Џ̓ĴИ˦Ê̷ư̫˜ЍR̀ R̀ 8.26 ˜Ѝ´˕ž̛̫Ȁɮč_οĮ̀DŽ 292 ͩ 8 ͥ ̨DŽěѠ¬ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . . . describe "with valid information" do . . . describe "after saving the user" do before { click_button submit } let(:user) { User.find_by(email: 'user@example.com') } it { should have_link('Sign out') } it { should have_title(user.name) } it { should have_selector('div.alert.alert-success', text: 'Welcome') } end end end end ǻUʨ˜ҹҷ ɽˎɽѠ¬҈ȷʌӎЈ̛Ȁ˕žĊɮč̨DŽ5 ɽ5 8.2 ω Ų)̫ sign_in ɟ˓ϬϽї˜ЍѫѐƊNjͮÞ5 Ĵ̛Ȁwū»ɕȰƯ *ĊÊ sign_in @user ƊþT5ŠR̀ 8.27 ȁ͈ R̀ 8.27 ̛Ȁ˕žĊ̶ȷ̨DŽ app/controllers/users_controller.rb class UsersController < ApplicationController . . . def create @user = User.new(user_params) if @user.save sign_in @user flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end . . 293 . end 8.2.6 ŖA Ĵ 8.1 ω KΑѐǻUϬų̫̓сYӎЈʆ¼_Ёf̛Ą̫̏DŽ̉Ǚ̶»̛Ȁ˸­Ѡ¬҈ȷ$ʴʄƄωǻ UƊϬų̓Ѡ¬Éι ̴À$ʴSessions ȸ¼ĩ̫ÌkےѴM5 REST ʖʐnew Ìk̛:̨DŽҹҷcreate Ìkų̨̓DŽ̫ѐ ͘ǻUіϬ˦Ê  destroy Ìk·Ҧ sessionų̓Ѡ¬Éι҂žѠ¬Éι̫˜ЍǻUþTʨ˜˸­Ѡ ¬҈ȷĊҹҷ ɮčɽ̨DŽ҈ȷŠR̀ 8.28 ȁ͈ R̀ 8.28 ˜Ѝ̛ȀѠ¬ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "signin" do . . . describe "with valid information" do . . . describe "followed by signout" do before { click_link "Sign out" } it { should have_link('Sign in') } end end end end ̨DŽÉιɮ̜ sign_in ɟ˓ų̫̓žư̫ǻU_n̛ sign_out ɟ˓ų̓Ѡ¬ÉιŠR̀ 8.29 ȁ͈ R̀ 8.29 ҉ʽ sessionų̓Ѡ¬Éι app/controllers/sessions_controller.rb class SessionsController < ApplicationController . . . def destroy 294 ͩ 8 ͥ ̨DŽěѠ¬ sign_out redirect_to root_path end end ě˜PсYӎЈ̷–̫ɟ˓ ʠǻU_Ĵ Sessions ȸ¼ĩ̫ƣÍɟ˓ʬĻ Ų) sign_out ɟ˓ɟ˓ʄс̫ų ̓NjͮÞǻUȏǃÀ̛ȀІ$ nil˼ĊĴ cookies Л̛ delete ɟ˓M session ·ҦЁǑʈʜŠR̀ 8.30 ȁ͈˜ųїѾˎǐϬȏǃÀ̛ȀІ$ nilĭ$Ĵ destroy Ìk ǻUʑ5тċɈkїѾǻU*ȁ Tї(‚ɮ$5›Źтċ̫Ѡ¬Ɉk R̀ 8.30 Sessions ƣÍɟ˓ʬĻ Ų)̫ sign_out ɟ˓ app/helpers/sessions_helper.rb module SessionsHelper def sign_in(user) remember_token = User.new_remember_token cookies.permanent[:remember_token] = remember_token user.update_attribute(:remember_token, User.encrypt(remember_token)) self.current_user = user end . . . def sign_out self.current_user = nil cookies.delete(:remember_token) end end ̓Ĵ˕ž̨DŽěѠ¬Éιѹų̓5˜Ѝ0ưВþTѫѐ5 $ bundle exec rspec spec/ ɽ ˸ҲϬ˕DZǻU̫˜Ѝϭ̱5сYӎЈʆ¼̫œŐɕÉιcɮ’ѸoŠǻUˎɽ˜Ѝ“Ёfǻ”»Ʊ Ёf5Ő'0ˎ˜ЍɮčІΦ5ЁǑʈʜǻUǃ˼þTʑїA˜ЍѐΒӎĔЊǻU̶ȷ˜Ѝ cookie ̫ ~þҶήϬqЯ™g̫ų̓Ύωήų̫̓ɟ˓ĴĈ̫ Rails ̂ʄ þι_ɽȁĈåtư̛͘ƮþT n̛˜Ѝæ_ŗХȁTǻUü–˕ȗП̫ÉιӎЈ̛ȀɮčþT̨DŽɮčþTwȥ̨DŽ̉ǙTîɮčþ TѠ¬Π¢̫˜ЍˎǐϬ҂žų̫̓Ύω 8.3 Cucumber Č ŘŅ ÀҷωŃʄŰǺ5͈o͘Ʈ̫сYӎЈ΀Ιї ωǻUƃKΑŠhn̛ Cucumber Π¢̨DŽ˜ЍCucumber ɮ ˚ϡ̫ϡ$ӌÌƷòBehavior-driven Development, BDDƘ™Ĵ Ruby ͉× áȰ̽ Ų̫ĵdʄω̫ ŹɮѥЙ̫lþT̶ȷнѐ_džĞĊ˝Ź 295 Cucumber n̛Ήɘʄ̫ɏ8storyȻѝư̛͘Ʈ̫ϡ$NjŐ Rails Ʒòέò̓n̛ Cucumber Ō̕ŴȀʥoɩ Ù¯ɟtĭ$ҵȎʅGĕ0ιЙǷїAϡ$ȻѝCucumber ˜ЍþT̛:ěŴȀˍѫ̙πΒƤɮ̜ŴȀʌΠ¢ ̫ǃ˼n̛ɮΉ Ruby R̀΍Ǻ̫˜ЍʤʖɽŮ̫ƎҤǝήǻіò̓Ήɘʄ̫ɏ8NjĥĨͰǚʠ Cucumber Ĵ Ruby ˜ЍƘ™ іɮɽ˜ūĴDZ)̫ǻ̆ºʯЮŮžȗПϡ$̫–˕ήɮʺ̵ƱƏ̫™gų ̓ ĭ$ʄ2̽ѿKΑ̫ɮ RSpec ě CapybaraȁTʄωž Cucumber ̫KΑNj˛ɯ0ŰɗNj՝Źѹˎ‚ГΎ ЗɪǻüɮǯϽlgӎ Šhn̛ CucumberŠʔldzϳҌþTҘЙҒKΑ Cucumber ̫2͵ˤ‘ŭ 1 υǻ_ȹϐlҘЙ David Chelimsky ̫The RSpec BookRyan Bigg ě Yehuda Katz ̫Rails 3 in ActionTî Matt Wynne ě Aslak Hellesøy ̫The Cucumber Book 8.3.1 „İhļġ ϋϬůϪ CucumberҲϬĴ Gemfile ̫ :test ΍ ʑ cucumber-rails ě database_cleaner ї gemŠR̀ 8.31 ȁ͈ R̀ 8.31 Ĵ Gemfile ʑ cucumber-rails . . . group :test do . . . gem 'cucumber-rails', '1.3.0', :require => false gem 'database_cleaner', github: 'bmabey/database_cleaner' end . . . ˼Ċě*À ʠѓϡ ĚSůϪ $ bundle install ŠʔϬĴ͘Ʈ n̛ CucumberǻUϬ̚Ǻ AȁҲ̫ɘVěɘVř $ rails generate cucumber:install їĚS_Ĵʢ̴DŽ µƶ features ɘVřCucumber ̷–̫ɘVѹ_ūĴїɘVř  296 ͩ 8 ͥ ̨DŽěѠ¬ 8.3.2 KħhãŻ† Cucumber ̫“Éιfeature”Ɗɮơʀư̛͘Ʈų̫̓ϡ$n̛ ͑ĉ$ Gherkin ̫ΉɘʄДϷΠ¢n̛ Gherkin Π¢̫˜Ѝě¢̫Njş̫ RSpec ˜Ѝ̛oƛŐѐĭ$ Gherkin ɮΉɘʄȁT̆ºѢćѶAɮNjǷ Ruby R̀ήþT̕ϵύД̫Gn̛ ҷǻUϬΠ¢ A Cucumber Éιų̓R̀ 8.5 ěR̀ 8.6 ҂ž̨DŽÉι̫Ѹ¯˜Ѝ̛oӊǻUĴ features ɘVř ɞƶĉ$ signing_in.feature ̫ɘV Cucumber ̫Éι̜ ̫ͮ̿ȻѝɘʄƷţŠȁ͈ Feature: Signing in ˼ĊŸ˦Ê ŲɕҀ̷ž̫̌͢ĶɲscenariooŠϬ˜Ѝ̨DŽŗХ̫ǧ¥ǻUþTȧ˽Š̫ɟƻΠ¢Ķ ɲ Scenario: Unsuccessful signin Given a user visits the signin page When he submits invalid signin information Then he should see an error message Ͷb̫˜Ѝ̨DŽǺÉɩǻUþTʑŠ̫Ķɲ Scenario: Successful signin Given a user visits the signin page And the user has an account When the user submits valid signin information Then he should see his profile page And he should see a signout link ȏѝ̫ɘʄɎĴ гƊ΍Ǻ5R̀ 8.32 ȁ͈̫ Cucumber ÉιɘV R̀ 8.31 ˜Ѝ̛Ą̏DŽÉι features/signing_in.feature Feature: Signing in Scenario: Unsuccessful signin Given a user visits the signin page When he submits invalid signin information Then he should see an error message Scenario: Successful signin Given a user visits the signin page And the user has an account When the user submits valid signin information 297 Then he should see his profile page And he should see a signout link ˼Ċn̛ cucumber ĚSѓϡїÉι $ bundle exec cucumber features/ ѝĚSěȆϡ RSpec ˜Ѝ̫ĚSͶb $ bundle exec rspec spec/ ȼ͈ Cucumber ě RSpec ʠþTѫѐ Rake ĚSȆϡ $ bundle exec rake cucumber ҁ:ʗAêĭǻΒƤn̛̫ĚSɮ rake cucumber:ok ǻUüɮ¢5 AΉɘʄȁT˃DZŏCucumber Ķɲ̓Ĵ_ѫѐϋϬϽ˜ЍѫѐǻUϬɞƶ ʷӏŲ )ɘVȏĶɲ ̫Ήɘʄě Ruby R̀žưгʌʷӏŲ)ɘVūɎĴ features/step_definition ɘVř ǻUϬƃ˜Ěĉ$ authentication_steps.rb T Feature ě Scenario ƷŘ̫ϡŃʄüϧϱkɘʦ˜P̫ϡ³ѹϬě Ruby R̀žưoŠÉιɘV ҷїϡ Given a user visits the signin page žư»ʷӏŲ) ̫ Given /ˆa user visits the signin page$/ do visit signin_path end ĴÉιɘV Given üɮɱѫ̫Ūͨ"ήĴʷӏŲ) Given ³ɮ ɟ˓þTȷô ʵ³ϥэƻk$ ìɕĊҷіþTк̽ ĻGiven ɟ˓̫ʵ³ϥэƻìɕɮ̛ʌÖѺÉιɘV ʗ̆Ųϡ̫Ļ ̫R̀³ ɮų̓Ȼѝ̫ϡ$ȁҲ̫ Ruby R̀ʄo ̫“a user visits the signin page”ɮ̜ҷїϡR̀ų̫̓ visit signin_path lþιϳnjїϡR̀Nj̼˾ҌїƊɮÀҷ̛ѐ̫ Capybara ȼp̫ɟ˓Cucumber ̫ʷӏŲ)ɘV_οÌƼ ‘ Capybaraȷʌ̫ϡR̀ų̓0Ĉʠ̼˾Š̫Ķɲʷӏ When he submits invalid signin information Then he should see an error message žư»ʷӏŲ)ɘV ̫ 298 ͩ 8 ͥ ̨DŽěѠ¬ When /^he submits invalid signin information$/ do click_button "Sign in" end Then /^he should see an error message$/ do expect(page).to have_selector('div.alert.alert-error') end ҷїʼR̫̀ͩ ʷіɮ̛5 Capybaraͩ9ʷ³Δć5 Capybara ̫ page ě RSpecNjɪɯ*ÀǻUn̛ RSpec ě Capybara Π¢̫˜ЍĴ Cucumber 0ɮɽ̛ʸ*ĵ̫ Ķɲ ȷʌ̫ʷӏ0þT‚Ͷb̫Ō̕ɼΐ̫ʷӏŲ)ɘVŠR̀ 8.33 ȁ͈lþT ʭü˦Ê ʷӏ˼ ĊȆϡҷ̫R̶̀»˜Ѝѹѫѐ$ʴ $ bundle exec cucumber features/ R̀ 8.32 n̨DŽÉιѫѐ̫ʷӏŲ) features/step_definitions/authentication_steps.rb Given /^a user visits the signin page$/ do visit signin_path end When /^he submits invalid signin information$/ do click_button "Sign in" end Then /^he should see an error message$/ do expect(page).to have_selector('div.alert.alert-error') end Given /^the user has an account$/ do @user = User.create(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end When /^the user submits valid signin information$/ do fill_in "Email", with: @user.email fill_in "Password", with: @user.password click_button "Sign in" end Then /^he should see his profile page$/ do expect(page).to have_title(@user.name) end 299 Then /^he should see a signout link$/ do expect(page).to have_link('Sign out', href: signout_path) end ˦Ê5R̀ 8.33Cucumber ˜ЍưВƊþTѫѐ5 $ bundle exec cucumber features/ 8.3.3 Œµ“ĩ† RSpec Pşk Π¢5 AͮÞ̫ Cucumber Ķɲ*ĊǻUʌě̷ư̫ RSpec ˜Ѝ̛ožˀ ̺ R̀ 8.32 ̫ Cucumber ÉιěR̀ 8.33 ̫ʷӏŲ)˼ĊŸ̺ Š̫ RSpec үǺ˜Ѝ describe "Authentication" do subject { page } describe "signin" do before { visit signin_path } describe "with invalid information" do before { click_button "Sign in" } it { should have_title('Sign in') } it { should have_selector('div.alert.alert-error', text: 'Invalid') } end describe "with valid information" do let(:user) { FactoryGirl.create(:user) } before do fill_in "Email", with: user.email.upcase fill_in "Password", with: user.password click_button "Sign in" end it { should have_title(user.name) } it { should have_link('Profile', href: user_path(user)) } it { should have_link('Sign out', href: signout_path) } it { should_not have_link('Sign in', href: signin_path) } end end end 300 ͩ 8 ͥ ̨DŽěѠ¬ ̜ʶlœʫƊþT̺¬ Cucumber ěүǺ˜ЍĆο̫^Σ˸5Cucumber ÉιþЙǝNjşcɮæě˜ЍR̀¯ҫ Ʒ5Ĉɩ¿ƿ5Éιě˜ЍR̫̀k̛ǻϳnj Cucumber ˜ЍЙгʌNjҼøcɮ¢гʌǞǞ̫ ήүǺ˜Ѝ ЙгʌŕҼøcɮNjŹɫΠ¢ Cucumber ȏÉιȻѝěʷӏŲ)¯ƷþTNjş̫ų̓ȗПƏҷ̫ϡ$oŠҷїȻѝ Then he should see an error message ϥэ̫DZǜɮʁʀ̺» ҌЕȼ͈xǠŠ̫ʷӏŲ)³ʨ˜5ιčų̓їʁʀ Then /^he should see an error message$/ do expect(page).to have_selector('div.alert.alert-error', text: 'Invalid') end Cucumber ї͑¯͎ɟƻ̆ºtȱ̫ĵɟĴ:üɽʷӏŲ)ɮqЯ™gų̫̓ȁT€ŠǻUyɌ5ҌЕȼ͈xǠ ȁ̛̫ CSS classÉιȻѝɘVɮҲϬyɌ̫ Ѷ(Šʔlüɮǯʨ˜ҹҷ ɮčɯ͈ɽҌЕȼ͈xǠƊǯĴŐĵɟѿŎ̫Π¢ҷ̫˜Ѝ should have_selector('div.alert.alert-error', text: 'Invalid') Šʔl̻̫ї(‚5Ɗȏ˜Ѝě™g̫ų̓Γʺ5 ɦɌõ5ų̓ɟƻƊϬ»ŌyɌ˜ЍĴ RSpec þ TοŲ)ÖѺĩʌϵ¤їҕӄǻUþT̶ȷї(¢ should have_error_message('Invalid') ǻUþTĴ 5.3.4 ω Ų) full_title ˜ЍƣÍɟ˓̫ɘV Ų)їÖѺĩR̀Š RSpec::Matchers.define :have_error_message do |message| match do |page| expect(page).to have_selector('div.alert.alert-error', text: message) end end ǻUіþT$ AƤ̛̫ɈkŲ)ƣÍɟ˓oŠ def valid_signin(user) fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Sign in" end ɼΐ̫ɘVŠR̀ 8.34 ȁ͈ȏ 5.6 ω ̫R̀ 5.38 ěR̀ 5.39 ćƫ5ǻϳnjї͑ɟ˓ˀ Cucumber ̫ʷӏŲ )іϬ˶˘̆ºɮǃÖѺĩěƣÍɟ˓þTȷô ìɕɩoŠ valid_signin(user)ǻU0þT̛ʷӏ Ų) ̫ʵ³ϥэƻÖѺʌų̓ї͑Éιѐŕѐ΅ʇ 301 R̀ 8.33 ˦Ê ƣÍ®ɕě  RSpec οŲ)ÖѺĩ spec/support/utilities.rb include ApplicationHelper def valid_signin(user) fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Sign in" end RSpec::Matchers.define :have_error_message do |message| match do |page| expect(page).to have_selector('div.alert.alert-error', text: message) end end ˦Ê5R̀ 8.34 *ĊǻUƊþT̶ȷ¢ it { should have_error_message('Invalid') } ě describe "with valid information" do let(:user) { FactoryGirl.create(:user) } before { valid_signin(user) } . . . іɽNjŐ˜Ѝ̛oȏ˜Ѝě™g̫ų̓ΓΡĴ г5ǻU_Ĵ 8.5 ω̫Ό1 LJƱ̫ȿʙ̓ɽ̫˜Ѝ΍Vn̛ οŲ)ÖѺĩěƣÍɟ˓ϵα˜Ѝě™gų̓ 8.4 ŒĘ ʄͥǻUKΑ5NjŐŃ̈́̾Љ0$͙ɯͮҡ̫ư̛͘Ʈų̓5˕žę̌DŽÉιų̓5̛ȀсYӎЈÉιĊǻ UƊþTʢǪ̇̄DŽ̉Ǚě̛Ȁ̫сYҤ¼ž̆Ųҹҷ̫ЇҕʈҤĴų̓Ҥ¼Їҕ̫ѐ͘ ǻU_$̛Ȁ˦ÊΠ щGxǠ̫Éιі_$Ͱ̕ĕ˦Ê·Ҧ̛Ȁ̫ÉιїAɮͩ 9 ̫ͥ%ϬŹ ĴΚΛҘЙ*Àȏʄ̫ͥɌÌćƫ»%¯ɊĎ $ git add . $ git commit -m "Finish sign in" $ git checkout master $ git merge sign-in-out 302 ˼ĊŸȹѡ» GitHub ě Heroku “̚C̒Ň”ɿËĩ $ git push $ git push heroku $ heroku run rake db:migrate ͩ 8 ͥ ̨DŽěѠ¬ 8.5 Ė 1. ѿʐ̨DŽϥÞȏ form_for ȮǺ form_tag͆w˜ЍіɮþTѫѐ̫ȼ͈ þTì˽ Railscasts ͩ 270 үAuthentication in Rails 3.1̆º̢DZ  params Hash Δʐ̫õÔ 2. ì˽ 8.3.3 ω ̫͈oѰϲ̛ȀěсYӎЈ̷–̫үǺ˜ЍĴ spec/support/utilities.rb Ų )ƣÍ®ɕϵα˜Ѝě™gų̓ҟÊӄ ȏїAƣÍɟ˓Ɏ»Ĉ̫ɘVěʬĻ ˼ĊŸƼ‘̷ư ̫ʬĻ 303 ʶҹ̢̩ ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ĉ 9 ć ÑËÐāhGŬö® ʄͥǻUϬŰǺϥʣ 7.1ȁ͈̫Users Ьˬ˦Ê editupdateindex ě destroy ÌkӊǻUϬų̓ɹɞ ̛ȀGЬə̫Éιų̓їʠ̫Éιο˼ϬqҶů’ӎЈ΀ΙŃ:ͩ 8 ͥ ų̫̓ʈҤҤ¼˼ĊϬµƶ ҹҷ²¬ȁɽ̛̫Ȁ0ҲϬʈҤҤ¼ʁҖ_KΑ͈oɕȰě¯ҹÉιɼĊǻUіϬų̓·Ҧ̛Ȁ̫ ÉιMɕȰƯ ·Ҧ̛ȀЁDŽǻU_$ȁɽ̛Ȁѹȼpї͑ǁœ̫ʈҤήɮ_µƶͰ̕ĕȲʈPUʌ· Ҧ̛Ȁ ĴƷţ*ÀǻUϬɞƶ updating-users ¯Ɋ $ git checkout -b updating-users 9.1 ÑËö® Πщ̛ȀxǠ̫ɟ˓ěµƶɞ̛ȀƛŐìϮͩ 7 ͥµƶɞ̛Ȁ̫ҹҷɮĴ new Ìk Ō̫̕ήΠщ̛Ȁ ̫ҹҷ³ɮĴ edit Ìk µƶ̛Ȁ̫ѐ͘ɮĴ create Ìk Ō̕5 POST ИˇήΠщ̛ȀϬĴ update Ì k Ō̕ PATCH ИˇHTTP ИˇìϮɡ˕ 3.39έ*Җɼœ̫׺ɮXhGѹþT˕žcüɽǃÀ̛Ȁ ȃιɹɞPοƜ̫xǠȁTǻUƊϬҤ¼ЇҕüɽȲʈ̛̫ȀȃιΠщɹɞЬəǻUþT¹̛ͩ 8 ͥų̫̓ сYӎЈʆ¼n̛”8Àѐ˰ĩbefore filter“ų̓ЇҕҤ¼ 9.1.1 ĞŏĮR ǻUʌµƶΠщϥÞ˜ʐǜijŠij 9.1 ȁ͈1ě*À ʠǻUϬΠ¢˜Ѝ˕DZʐǜij yɌ Gravatar Ř ˆ̫҈ȷŠʔl˝ϲѐ Gravatar ̫ΤͤþιƊ̾ѱ`ěΠщ؈̫ĵĸɮ http://gravatar.com/emailsǻUƊ ʌ˜ЍΠщҹҷ ɽˎɽ ҈ȷȦċ5їĵĸ2 žΠщ̛ȀϥÞ̫˜ЍěͩͥΌ1 ̫R̀ 7.31 ͶbĈʠ0˜Ѝ5ȼBć˓ɕȰĊɮč_ɯ͈ҌЕȼ͈x ǠŠR̀ 9.1 ȁ͈ R̀ 9.1 ̛ȀΠщҹҷ̫˜Ѝ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . . 1. ij́ʌο http://www.flickr.com/photos/sashawolff/4598355045/ 2. Gravatar _ȏїĵĸтċ http://en.gravatar.com/emailsǻëȳ5Àҷ̫ enїʠѥȟ˜PДϷ̛̫ȀƊ_οÌтċ̷ư̫ҹ ҷ5 305 . describe "edit" do let(:user) { FactoryGirl.create(:user) } before { visit edit_user_path(user) } describe "page" do it { should have_content("Update your profile") } it { should have_title("Edit user") } it { should have_link('change', href: 'http://gravatar.com/emails') } end describe "with invalid information" do before { click_button "Save changes" } it { should have_content('error') } end end end 306 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ij 9.1 Πщ̛Ȁҹҷ̫ʐǜij ͘ƮȁҲ̫R̀ϬɎĴ edit Ìk ǻUĴϥʣ 7.1 ²¬5̛ȀΠщҹҷ̫ĵĸɮ /users/1/edit€І̛Ȁ̫ id ɮ 1ǻUKΑѐ̛Ȁ̫ id ɮwūĴ params[:id] ̫ȁTǻUþTȧ˽R̀ 9.2 ȁ͈̫ɟ˓ʙƠ̏Ȁ R̀ 9.2 Users ȸ¼ĩ̫ edit ɟ˓ app/controllers/users_controller.rb class UsersController < ApplicationController . . . def edit @user = User.find(params[:id]) end . . . end ϬϽ˜ЍѫѐǻUƊϬΠ¢Πщ̛Ȁҹҷ̫ϱijŠR̀ 9.3 ȁ͈OΎϯż ϱijR̀ŮěR̀ 7.17 µ ƶɞ̛Ȁҹҷ̫ϱijR̀Nj̷bїƊɶ͈ǻUϬјϡѿʐȏѿŎ̫R̀͗‘ƎѸϱijѿʐ_̢kΌ1Гǧ ìϮ 9.6 ω R̀ 9.3 Πщ̛Ȁҹҷ̫ϱij app/views/users/edit.html.erb <% provide(:title, "Edit user") %>

Update your profile

<%= form_for(@user) do |f| %> <%= render 'shared/error_messages' %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :email %> <%= f.text_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirm Password" %> <%= f.password_field :password_confirmation %> <%= f.submit "Save changes", class: "btn btn-large btn-primary" %> 307 <% end %> <%= gravatar_for @user %> change
ĴїʼR̀ ǻUŸʭn̛5 7.3.3 ω µƶ̫ error_messages ƎѸϱij ˦Ê5ϱijR̀ŸÊR̀ 9.2 Ų)̫ @user õҀR̀ 9.1 ̫“Πщҹҷ”˜ЍưВƊþTѫѐ5 $ bundle exec rspec spec/requests/user_pages_spec.rb -e "edit page" Πщ̛ȀҹҷŠij 9.2 ȁ͈ǻU̺» Rails _οÌЙó @user õҀӀņş5ĉŪě Email ĵĸŪʼ ij 9.2 Πщ̛ȀҹҷĉŪě Email ĵĸŪʼƝΒοÌņş5 ʙ̺ Πщ̛Ȁҹҷ̫ˬ̀ǻUþTò̫̓͆̚Ǻ5  form ‹΁ìϮR̀ 9.4 R̀ 9.4 ΠщϥÞ̫ HTML
. 308 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ . .
̢DZ ˜ ̫ ҪϙŪʼ ĭ$˝ϲĩʄсƫɊȥòѡ PATCH Иˇϥʣ 7.1 ²¬̫ REST ÌkϬ̛ȁT Rails ƊĴ POST Иˇ n̛ їҪϙŪʼaѭ5  PATCH Иˇ3 іɽ ΎωҲϬ˕DZ R̀ 9.3 ěR̀ 7.17 ѹn̛5̷Ĉ̫ form_for(@user) ʌʐƶϥÞѶ( Rails ɮ ǚ(̾ѱµƶɞ̛ȀϬòѡ POST ИˇήΠщ̛ȀɩϬòѡ PATCH Иˇ̫Ė їҕӄ̫ͫʥɮѫѐ Active Record ȼp̫ new_record? ɟ˓þTʨ˜̛Ȁɮɞµƶ̫іɮƝΒūĴ:ɕȰƯ ̫ $ rails console >> User.new.new_record? => true >> User.first.new_record? => false ȁTĴn̛ form_for(@user) ʐƶϥÞɩŠʔ @user.new_record? ѕĬ true ³òѡ POST Иˇč³Ɗ òѡ PATCH Иˇ ɼĊǻUіϬĴƀτ ˦Ê ȦċΠщ̛Ȁҹҷ̫҈ȷ“ІΦSettings”ĭ$üɽ̨DŽ*Ċȃ_ɯ͈ї ҹҷȁTž“ІΦ”҈ȷ̫˜ЍϬě˜P̫сYӎЈ˜ЍɎĴ гŠR̀ 9.5 ȁ͈ŠʔιŸ˜Ѝ ˎ̨ DŽɩ_ɯ͈“ІΦ”҈ȷƊɹŰΨ5ї_̢kΌ1ìϮ 9.6 ω R̀ 9.5 ˦Êʨ˜“ІΦ”҈ȷ̫˜Ѝ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "with valid information" do let(:user) { FactoryGirl.create(:user) } before { sign_in user } it { should have_title(user.name) } it { should have_link('Profile', it { should have_link('Settings', it { should have_link('Sign out', href: user_path(user)) } href: edit_user_path(user)) } href: signout_path) } 3. ϬȘǏų̫̓Ύω™g̫ų̓ɟƻɮ Rails ʤʖ̫ƷòέҲϬ–˕̫k$ Rails ͘ƮƷòέ³ɣҲ–Ǐ 309 it { should_not have_link('Sign in', href: signin_path) } . . . end end end $5ͮÔR̀ 9.5 n̛ sign_in ƣÍɟ˓їɟ˓̫k̛ɮЇҕ̨DŽҹҷȼBć˓̫ϥÞɕȰŠR̀ 9.6 ȁ͈ R̀ 9.6 ̛Ą̏DŽƣÍɟ˓ spec/support/utilities.rb . . . def sign_in(user, options={}) if options[:no_capybara] # Sign in when not using Capybara. remember_token = User.new_remember_token cookies[:remember_token] = remember_token user.update_attribute(:remember_token, User.encrypt(remember_token)) else visit signin_path fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Sign in" end end ŠѝR̀ ̫˕ѽȁЗŠʔˎɽn̛ Capybara ̫Џņ¢ϥÞ̫Ɉkɮɣɐ̫ȁTǻUȼp5 no_capybara: true ѥһнѐәϻ̨̫DŽɈk̶ȷŌ̕ cookieŠʔ̶ȷn̛ HTTP Иˇɟ˓ƊǐҽϬɽ ҷїϡR̀™g̛̫˓ĴR̀ 9.47 ɽKΑ˕DZ˜Ѝ n̛̫ cookies žПě̻ų̫ cookies žПɮɽ ˸ ʠ̫R̀ 8.19 n̛̫ cookies.permanent ɟ˓ιĴ˜Ѝ n̛lþιƝΒ̎»5sing_in ĴĊΛ̫˜Ѝ і_̛»ήіþT̛ʌëҦѿŎR̀ìϮ 9.6 ω Ĵ͘Ʈ ˦Ê“ІΦ”҈ȷNjͮÞǻUƊ̶ȷn̛ϥʣ 7.1 ²¬̫ edit_user_path ™ĉм̜˜ìɕІ$R ̀ 8.22 Ų)̫ current_user ƣÍɟ˓ <%= link_to "Settings", edit_user_path(current_user) %> Űɗ̫R̀ŠR̀ 9.7 ȁ͈ R̀ 9.7 ˦Ê“ІΦ”҈ȷ app/views/layouts/_header.html.erb 310 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ 9.1.2 Ğŏ|ň ʄƄωǻUϬŌ̕ΠщŗХ̫ǧ¥ϽR̀ 9.1 žҌЕȼ͈xǠ̫˜ЍѫѐǻUϬĴ Users ȸ¼ĩ̫ update Ìk n̛ update_attributes ɟ˓`‘ȼB̫ params Hashɹɞ̛ȀЁDŽŠR̀ 9.8 ȁ͈ŠʔȼB 5ć˓̫ɕȰɹɞɈk_ѕĬ falseB̜ else ¯ɊŌ̕ѿɞ˪ʘΠщ̛ȀҹҷǻU*À̛ѐͶb̫Ō ̕ɟƻR̀Δʐěͩ ̂ʄ̫ create ÌkͶbìϮR̀ 7.21 R̀ 9.8 іŰɗ̫ update Ìk app/controllers/users_controller.rb class UsersController < ApplicationController . . 311 . def edit @user = User.find(params[:id]) end def update @user = User.find(params[:id]) if @user.update_attributes(user_params) # Handle a successful update. else render 'edit' end end . . . end ˕DZĴЛ̛ update_attributes ɟ˓ɩȦŲ̫ user_params ìɕї̛͑˓ɮ“„Ŋìɕ”strong parameterþTѵ mass assignment ˱˗ìϮ 7.3.2 ω ij 9.3 ȼBΠщϥÞĊɯ͈̫ҌЕȼ͈xǠ 312 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ȼBć˓xǠĊɯ͈5ҌЕȼ͈xǠŠij 9.3˜ЍƊþTѫѐ5lþTѓϡ˜Ѝ΍VӎЈ  $ bundle exec rspec spec/ 9.1.3 Ğŏ¬K ̓ĴǻUϬϽΠщϥÞιŒʵƤn̛5Πщ؈̫ÉιƝΒų̓5ĭ$ǻUȏ`؈̫ɈkB̜ Gravatar Ō ̕5ŠҲɹȮ؈˸­ij 9.2 ̫“change”҈ȷƊþT5Šij 9.4 ȁ͈ҷǻUʌų̓Πщ˜PxǠ̫É ι ij 9.4 Gravatar ̫Ä°ij̠́ҷ`5 Ɵğ̫ij́ ž update Ìk̫˜Ѝěž create ̫˜ЍͶbR̀ 9.9 KΑ5Šhn̛ Capybara ĴϥÞ ņ¢ć˓̫ɕȰі KΑ5ǚ(˜ЍȼBϥÞ̫Ɉkɮčʵ͆˜Ѝ̫R̀NjŐlþTìάͩ 7 ͥ ̫˜ЍЍ ιιے̕ ϵ R̀ 9.9 ˜Ѝ Users ȸ¼ĩ̫ update Ìk spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . 313 . . describe "edit" do let(:user) { FactoryGirl.create(:user) } before { visit edit_user_path(user) } . . . describe "with valid information" do let(:new_name) { "New Name" } let(:new_email) { "new@example.com" } before do fill_in "Name", with: new_name fill_in "Email", with: new_email fill_in "Password", with: user.password fill_in "Confirm Password", with: user.password click_button "Save changes" end it { should have_title(new_name) } it { should have_selector('div.alert.alert-success') } it { should have_link('Sign out', href: signout_path) } specify { expect(user.reload.name).to eq new_name } specify { expect(user.reload.email).to eq new_email } end end end ѝR̀ ¬̓5 ɞ̫ɟ˓ reload¬̓Ĵʨ˜̛Ȁ̫ƓǝɮčƝΒɹɞ̫˜Ѝ specify { expect(user.reload.name).to == new_name } specify { expect(user.reload.email).to eq new_email } їϡR̀n̛ user.reload M˜ЍɕȰƯ ѿɞÊц user ̫ɕȰ˼Ċʨ˜̛Ȁ̫ĉŪě Email ĵĸɮčɹ ɞǺ5ɞ̫~ ϬϽR̀ 9.9 ̫˜ЍѫѐǻUþTì˽ɼΐ̂ʄ̫ create ÌkR̀ 8.27ʌΠ¢ update ÌkŠR̀ 9.10 ȁ͈ǻUĴR̀ 9.8 ̫Ń̈́ʑ5ҷїϡ flash[:success] = "Profile updated" sign_in @user redirect_to @user ˕DZ̛ȀЬəɹɞǺÉ*ĊǻUŸʭ̨‘5̛Ȁĭ$wư̄ȀɩѿІ5ЁǑʈʜR̀ 8.18*À̫ session Ɗŗɐ5R̀ 8.22ї0ɮ һů’Ⱥɠĭ$Šʔ̛Ȁɹɞ5ЬəXh_ЏÎȥѹ_οÌŗɐ 314 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ R̀ 9.10 Users ȸ¼ĩ̫ update Ìk app/controllers/users_controller.rb class UsersController < ApplicationController . . . def update @user = User.find(params[:id]) if @user.update_attributes(user_params) flash[:success] = "Profile updated" sign_in @user redirect_to @user else render 'edit' end end . . . end ˕DZ̓Ĵї͑ų̓ɟƻʿʭɹɞɕȰѹϬȼpź̀ņ¢ij 9.2 Ѷ̫͝Ūʼϝ˼ɽ˸˻Gѐæ wЈ5ů’ ˦Ê5ʄƄω̫R̀*ĊΠщ̛ȀҹҷưВþTʵƤn̛5lþTѓϡ˜Ѝ΍VŸ͆ϻ ˜ЍưВɮþT ѫѐ̫ $ bundle exec rspec spec/ 9.2 ÕūūI ͩ 8 ͥ ų̫̓сYӎЈʆ¼ɽ Njş̫k̛þTų̓ʈҤҤ¼сYӎЈþTЉº̛ȀɮčƝΒ˕žήʈ ҤҤ¼³þTҤ¼̛ȀþTјϡ̫Ɉk ϝ˼ 9.1 ω ƝΒŃʄŰǺ5 edit ě update Ìkcɮæɽ ů’ҪǤ XhG̙πɮʂ̨DŽ̛̫Ȁѹ þTЇҕїÌkή̨DŽĊ̛̫ȀþTɹɞȁɽ˜P̛Ȁ̫ЬəʄωǻUϬų̓ ͑ů’ʆ¼Ҥ¼̛Ȁ ǐҽ̨DŽȃιɹɞοƜ̫ЬəήιɹɞPG̫Ьəˎɽ̨DŽ̛̫ȀŠʔЍijЇҕїAôwȓ̫ҹҷ_т ċ̨DŽҹҷƫɯ͈ ȼ͈xǠʐǜijŠij 9.5 ȁ͈ 9.2.1 §Ŵ7ú¥ ĭ$ž edit ě update Ìkȁ‚̫ů’Ҥ¼ɮ ʠ̫ȁTǻUƊĴĈ  RSpec describe Ļ јϡ˜Ѝǻ UMϬˇ̨DŽƷţ˜ЍR̀Ϭʨ˜ʂ̨DŽ̛̫ȀЍijЇҕїÌkɩɮčтċ5̨DŽҹҷŠR̀ 9.11 ȁ͈ R̀ 9.11 ˜Ѝ edit ě update ÌkɮčŌ:ϧwȓ̉Ǚ 315 spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do describe "for non-signed-in users" do let(:user) { FactoryGirl.create(:user) } describe "in the Users controller" do describe "visiting the edit page" do before { visit edit_user_path(user) } it { should have_title('Sign in') } end describe "submitting to the update action" do before { patch user_path(user) } specify { expect(response).to redirect_to(signin_path) } end end end end end R̀ 9.11 Ҧ5n̛ Capybara ̫ visit ɟ˓*ŏіͩ ʭn̛5û ͑Їҕȸ¼ĩÌk̫ɟ˓ ŠʔҲϬ̶ȷò гʗ͑ HTTP Иˇ³̶ȷn̛ HTTP ÌЋžư̫ɟ˓åþoŠʄo ̫ patch òг̫Ɗɮ PATCH Иˇ describe "submitting to the update action" do before { patch user_path(user) } specify { expect(response).to redirect_to(signin_path) } end ѝR̀_ċ /users/1 ĵĸòѡ PATCH Иˇ̜ Users ȸ¼ĩ̫ update ÌkŌ̕ìϮϥʣ 7.1ǻUǐҽї (‚ĭ$˝ϲĩɣ˓̶ȷЇҕ update ÌkǐҽȼBΠщϥÞȁT Capybara 0‚»ЇҕΠщЬəҹҷ üι˜Ѝ edit ÌkɮčɽʈҤΚΛɈkήι˜Ѝ update Ìk̫Ȳʈǧ¥ȁTŠʔϬ˜Ѝ update Ìk ɮčɽʈҤјϡɈküι̶ȷòѡ PATCH ИˇlþιƝΒ̎»5Ҧ5 patch ɟ˓*ŏRails ̫˜ЍіɊ ȥ getpost ě delete ɟ˓ ̶ȷòѡʗ͑ HTTP ИˇɩǻUҲϬŌ̕ɹƱƏ̫ response žПě Capybara ȼp̫ page žПĈǻU þTn̛ response ˜ЍɿËĩ̫ĞưʄoǻUʨ˜5 update Ìk̫Ğưɮčтċ5̨DŽҹҷ 316 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ specify { expect(response).to redirect_to(signin_path) } ij 9.5 ЇҕôwȓҹҷтċĊ̫ҹҷʐǜij ǻUϬn̛ before_action ɟ˓ų̓ʈҤҤ¼їɟ˓_ĴȦŲ̫ÌkȆϡ*ÀѓϡȦŲ̫ɟ˓$5ų ̓Ϭˇ̛Ȁ̨DŽ̫Ҥ¼ǻUϬŲ) ĉ$ signed_in_user ̫ɟ˓˼ĊЛ̛ before_action :signed_in_userŠR̀ 9.12 ȁ͈ R̀ 9.12 ˦Ê signed_in_user 8Àѐ˰ĩ app/controllers/users_controller.rb class UsersController < ApplicationController before_action :signed_in_user, only: [:edit, :update] . . . private def user_params params.require(:user).permit(:name, :email, :password, 317 :password_confirmation) end # Before filters def signed_in_user redirect_to signin_url, notice: "Please sign in." unless signed_in? end end әϻǧ¥8Àѐ˰ĩ_ư̛:ȸ¼ĩ ̫ȁɽÌkȁTĴѝR̀ ǻU`‘5 :only ìɕȦŲüư̛Ĵ edit ě update Ìk ij 9.6 ƉЍЇҕôwȓ̫ҹҷĊɯ̨͈̫DŽϥÞ ˕DZĴR̀ 9.12 ǻUn̛5ІŲ flash[:notice] ̫ͮtɟƻȏ redirect_to ɟ˓̫ͩ9ìɕȦŲ$  HashїʼR̀ͪĈ: unless signed_in? flash[:notice] = "Please sign in." redirect_to signin_url end 318 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ flash[:error] 0þTn̛ѝ̫ͮtɟƻc flash[:success] æþT flash[:notice] Ê flash[:success] ě flash[:error] ƊɮǻUϬKΑ̫͑ Flash ˟ǠBootstrap $ ї͑˟Ǡѹȼp5ʠƻѠ¬ĊŸƉЍЇҕ /users/1/editƊ_̺»Šij 9.6 ȁ͈̫ӗχȼ͈ʤ ĴƉЍϽR̀ 9.11 ʨ˜ʈҤҤ¼̫˜Ѝѫѐ̫ѐ͘ ǻUæ͂ĺ5R̀ 9.1 ̫˜ЍŠ̫R̀ describe "edit" do let(:user) { FactoryGirl.create(:user) } before { visit edit_user_path(user) } . . . ̓Ĵ_ŗХĭ$ǐҽ̨DŽȃιʵƤЇҕΠщ̛ȀЬəҹҷϵ¤їҕӄ̫È˓ɮn̛R̀ 9.6 Ų)̫ sign_in ɟ˓̨‘̛ȀŠR̀ 9.13 ȁ͈ R̀ 9.13 $ edit ě update ˜Ѝʑ̨DŽȁҲ̫R̀ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . . . describe "edit" do let(:user) { FactoryGirl.create(:user) } before do sign_in user visit edit_user_path(user) end . . . end end ̓Ĵȁɽ̫˜ЍưВѹþTѫѐ5 $ bundle exec rspec spec/ 319 9.2.2 ö®]ħĞŏĩ•ûʼnÊ ǃ˼Ϭˇ̛Ȁǐҽ̨DŽіɮŒ̛̫ȀǐҽüιΠщοƜ̫ЬəǻU̫˜ЍþTї(Π¢̛˜P̛Ȁ̫ сY̨DŽ˼ĊЇҕ edit ě update ÌkŠR̀ 9.14 ȁ͈˕DZ̛ȀưВƉЍΠщ˜P̛Ȁ̫ЬəǻU ˎɽтċ̨DŽҹҷήɮт»5Τ̫ͤӊҹ R̀ 9.14 ˜ЍüɽοƜȃιЇҕ edit ě update Ìk spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do . . . describe "as wrong user" do let(:user) { FactoryGirl.create(:user) } let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") } before { sign_in user, no_capybara: true } describe "visiting Users#edit page" do before { visit edit_user_path(wrong_user) } it { should_not have_title(full_title('Edit user')) } end describe "submitting a PATCH request to the Users#update action" do before { patch user_path(wrong_user) } specify { expect(response).to redirect_to(root_path) } end end end end ˕DZµƶӀʐV̫ɟ˓іþTȷôͩ9ìɕ FactoryGirl.create(:user, email: "wrong@example.com") ѝR̀_̛ȦŲ̫ Email ɻȮәϻ~˼Ċµƶ̛ȀǻU̫˜ЍϬ͆w˜P̛̫ȀιЇҕêʌѶ̛Ȁ̫ edit ě update Ìk ǻUĴȸ¼ĩ ʑ5ͩ98Àѐ˰ĩЛ̛ correct_user ɟ˓ŠR̀ 9.15 ȁ͈ R̀ 9.15 wȓ edit ě update Ìk̫ correct_user 8Àѐ˰ĩ 320 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ app/controllers/users_controller.rb class UsersController < ApplicationController before_action :signed_in_user, only: [:edit, :update] before_action :correct_user, only: [:edit, :update] . . . def edit end def update if @user.update_attributes(user_params) flash[:success] = "Profile updated" sign_in @user redirect_to @user else render 'edit' end end . . . private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end # Before filters def signed_in_user redirect_to signin_url, notice: "Please sign in." unless signed_in? end def correct_user @user = User.find(params[:id]) redirect_to(root_path) unless current_user?(@user) end end ѝR̀ ̫ correct_user ɟ˓n̛5 current_user? ɟ˓ǻUϬĴ Sessions ƣÍɟ˓ʬĻ Ų)  ŠR̀ 9.16 R̀ 9.16 Ų) current_user? ɟ˓ app/helpers/sessions_helper.rb 321 module SessionsHelper . . . def current_user remember_token = User.encrypt(cookies[:remember_token]) @current_user ||= User.find_by(remember_token: remember_token) end def current_user?(user) user == current_user end . . . end R̀ 9.15 Ĉɩ0ɹɞ5 edit ě update Ìk̫R̀*ÀĴR̀ 9.2 ǻUɮїʠ¢̫ def edit @user = User.find(params[:id]) end update R̀Ͷbɤ˼ correct_user 8Àѐ˰ĩ ƝΒŲ)5 @userїÌk ƊŸҲϬŸŲ) @user õҀ5 ĴΚΛҘЙ*ÀlưВӎЈ ˜ЍɮčþTѫѐ $ bundle exec rspec spec/ 9.2.3 ÑXûŎd ͘Ʈ̫ʈҤҤ¼ŃʄŰǺ5cɮіɽ ˸ƄƄ̫з Ͱ̛ȀƉЍЇҕ̫ɮĠôwȓ̫ҹҷ̨DŽĊѹ_т ċЬəҹҷ0ƊɮЗŠʔʂ̨DŽ̛̫ȀЇҕ5ΠщЬəҹҷ_Ϭˇ̨DŽ̨DŽт»̫ҹҷɮ /users/1ή ɮ /users/1/editŠʔ̨DŽĊιт»̛Ȁ*ÀǯЇҕ̫ҹҷƊɹş5 ҂žї͑ɹïş̫тċǻUþTїʠΠ¢˜ЍЇҕΠщ̛ȀЬəҹҷтċ̨DŽҹҷĊņ¢ʵ̨̫͆DŽx Ǡ˸­“Sign in”ȧ҄˼Ċɯ͈̫ưВɮΠщ̛ȀЬəҹҷήɮ̛ȀЬəҹҷ̷ư̫˜ЍŠR̀ 9.17 ȁ ͈ R̀ 9.17 ˜Ѝɹïş̫тċ spec/requests/authentication_pages_spec.rb require 'spec_helper' 322 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ describe "Authentication" do . . . describe "authorization" do describe "for non-signed-in users" do let(:user) { FactoryGirl.create(:user) } describe "when attempting to visit a protected page" do before do visit edit_user_path(user) fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Sign in" end describe "after signing in" do it "should render the desired protected page" do expect(page).to have_title('Edit user') end end end . . . end . . . end end ҷǻUʌų̓їІǯ4Ϭтċ̛Ȁ̻ʵǯЇҕ̫ҹҷǻUϬĴʗĵɟū‡їҹҷ̫ĵĸ̨DŽĊŸтċ їҹҷǻUϬѫѐɟ˓ʌų̓їѐ͘store_location ě redirect_back_orѹĴ Sessions ƣÍ ɟ˓ʬĻ Ų)ŠR̀ 9.18 R̀ 9.18 ų̓ɹïş̫тċȁҲ̫R̀ app/helpers/sessions_helper.rb module SessionsHelper . . . 4. ų̫̓R̀ʌο thoughtbot ̫ Clearance gem 323 def redirect_back_or(default) redirect_to(session[:return_to] || default) session.delete(:return_to) end def store_location session[:return_to] = request.fullpath end end ĵĸ̫ū‡n̛5 Rails ȼp̫ sessionsession þT̕ϵǺě 8.2.1 ω KΑ̫ cookies ɮͶb̫ϫ_ Ĵ˝ϲĩ–ҔĊοÌŗɐĴ 8.5 ω KΑѐ˜ų session ̫ų̓ɟ˓ʵɮŠʶǻUіn̛5 request žП̫ fullpath ɟ˓ϓó5ȁИˇҹҷ̫ŰɗĵĸĴ store_location ɟ˓ ȏŰɗ̫Иˇĵĸū‡Ĵ session[:return_to]  Ϭn̛ store_locationǻUϬȏŮʑ signed_in_user 8Àѐ˰ĩ ŠR̀ 9.19 ȁ͈ R̀ 9.19 ȏ store_location ʑ signed_in_user 8Àѐ˰ĩ app/controllers/users_controller.rb class UsersController < ApplicationController before_action :signed_in_user, only: [:edit, :update] before_action :correct_user, only: [:edit, :update] . . . def edit end . . . private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end # Before filters def signed_in_user unless signed_in? store_location redirect_to signin_url, notice: "Please sign in." end end 324 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ def correct_user @user = User.find(params[:id]) redirect_to(root_path) unless current_user?(@user) end end ų̓тċɈkϬĴ Sessions ȸ¼ĩ̫ create Ìk ʑ redirect_back_or ɟ˓̛Ą̏DŽĊт»Ѣǃ̫ҹ ҷŠR̀ 9.20 ȁ͈Šʔū‡5*ÀИˇ̫ĵĸredirect_back_or ɟ˓Ɗ_тċїĵĸč³_тċì ɕ ȦŲ̫ĵĸ R̀ 9.20 ʑïşтċĊ̫ create Ìk app/controllers/sessions_controller.rb class SessionsController < ApplicationController . . . def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) sign_in user redirect_back_or user else flash.now[:error] = 'Invalid email/password combination' render 'new' end end . . . end Šʔl‚5ͩ 8 ̫ͥΌ1 1ЁnjȏR̀ 9.20 ̫ params Hash Ȯȳ redirect_back_or ɟ˓ĴҷїϡR̀ n̛5“Ǽ”Ɉkͨ || session[:return_to] || default Šʔ session[:return_to] ̫~ɮ nilҷїϡR̀Ɗ_ѕĬ session[:return_to] ̫~č³_ѕ Ĭ default˕DZĴR̀ 9.18 ǺÉтċĊƊ_·Ҧū‡Ĵ session ̫тċĵĸŠʔ·Ҧ̫ЏĴ–Ҕ ˝ϲĩ*Àʿʭ̨DŽĊѹ_т»ū‡̫ĵĸžї ѐ̫͘˜Ѝ̢kΌ1ìϮ 9.6 ω ʑѝR̀*ĊR̀ 9.17 žïşтċ̫үǺ˜ЍưВþTѫѐ5πʶǻU0ƊŰǺ5Ńʄ̛̫ȀсYӎ Јěҹҷwȓʆ¼ě*À ʠĴΚΛҘЙ*Àɼş͆ϻ ȁɽ̫˜ЍɮčѹþTѫѐ 325 $ bundle exec rspec spec/ ij 9.7 ̛Ȁ²ϥҹҷ̫ʐǜijÓď5¯ҹ҈ȷě“Users”ƀτ҈ȷ 9.3 DA¯Òö® ʄωǻUϬ˦ÊϹ± ̫zɕͩ9̛ȀÌkindexindex Ìk_ɯ͈ʗ ̛Ȁήɮɯ͈ȁɽ̛̫Ȁ Ĵїѐ͘ ǻUϬŭ1ŠhĴɕȰƯ ̚Ǻ͈ơȀɕȰTîŠh¯ҹɯ̛͈Ȁ²ϥɯ͈XDZɕҀ̛̫ Ȁ̛Ȁ²ϥ¯ҹ҈ȷě“ȁɽ̛ȀUsers”ƀτ҈ȷ̫ʐǜijŠij 9.7 ȁ͈5Ĵ 9.4 ω ǻUі_Ĵ̛Ȁ² ϥ ˦Ê·Ҧ҈ȷїʠƊþT·Ҧɽҕӄ̛̫Ȁ5 9.3.1 ö®DĮ Þ̛Ȁ̫ЬəҹҷɮžŏƷɎ̫ѐ̛Ȁ²ϥҹҷüɽ˕ž̛ȀȃιЇҕǻUʌΠ¢˜ЍĴ˜Ѝ ǻU Ϭʨ˜ index Ìkɮϧwȓ̫ŠʔЇҕ users_path _тċ̨DŽҹҷě˜P̫ʈҤҤ¼˜Ѝ ʠǻU0_ ȏї˜ЍɎĴсYӎЈ̫үǺ˜Ѝ ŠR̀ 9.21 ȁ͈ 5. ŧ‰̫ij́ʌο http://www.flickr.com/photos/glasgows/338937124/ 326 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ R̀ 9.21 ˜Ѝ index Ìkɮčɮϧwȓ̫ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do describe "for non-signed-in users" do . . . describe "in the Users controller" do . . . describe "visiting the user index" do before { visit users_path } it { should have_title('Sign in') } end end . . . end end end ϋϬї˜ЍѫѐǻUϬȏ index Ìkʑ signed_in_user 8Àѐ˰ĩŠR̀ 9.22 ȁ͈ R̀ 9.22 Їҕ index Ìkǐҽ̨DŽ app/controllers/users_controller.rb class UsersController < ApplicationController before_action :signed_in_user, only: [:index, :edit, :update] before_action :correct_user, only: [:edit, :update] def index end def show @user = User.find(params[:id]) end . . 327 . end ȷʌǻUϬ˜Ѝ̛Ą̏DŽĊ̛Ȁ²ϥҹҷϬɽ̆Ų̫ʜӄ읬іϬ²¬Τͤ ȁɽ̛̫Ȁ$ʶǻU Ϭµƶ̛ȀӀʐVTͩ ̛Ȁ̫сY̨DŽ˼Ċʨ˜̛Ȁ²ϥҹҷ ɮčɽ ²ϥĆ̛Ȁ̫ĉŪѹÓ ďĴ Þ̫̌ li ʜͭ ˕DZǻUϬ$ʿ̛Ȁ¯ѺĈ̫ĉŪїʠ²ϥ ̛̫Ȁȃɮ ʠ̫ŠR̀ 9.23 ȁ͈ R̀ 9.23 ̛Ȁ²ϥҹҷ̫˜Ѝ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do subject { page } describe "index" do before do sign_in FactoryGirl.create(:user) FactoryGirl.create(:user, name: "Bob", email: "bob@example.com") FactoryGirl.create(:user, name: "Ben", email: "ben@example.com") visit users_path end it { should have_title('All users') } it { should have_content('All users') } it "should list each user" do User.all.each do |user| expect(page).to have_selector('li', text: user.name) end end end . . . end lþιіЁnjǻUĴ˲͈͘Ʈ̷̫–R̀ KΑѐìϮR̀ 2.4Ĵ͘Ʈ ǻUþTn̛ User.all MɕȰ Ư óĬȁɽ̛̫ȀЭ~ΖųoõҀ @users Ĵϱij n̛ŠR̀ 9.24 ȁ͈lþι_ϳnj ʭ²¬ȁɽ̫ ̛Ȁŕşlɮž̫ǻU_Ĵ 9.3.3 ω Ɍј R̀ 9.24 Users ȸ¼ĩ̫ index Ìk app/controllers/users_controller.rb 328 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ class UsersController < ApplicationController before_action :signed_in_user, only: [:index, :edit, :update] . . . def index @users = User.all end . . . end Ϭɯ̛͈Ȁ²ϥҹҷǻUϬµƶ ϱijѰèȁɽ̛̫ȀȏÞ̛ȀÓďĴ li ʜͭ ǻUϬn̛ each ɟ˓Ѱèȁɽ̛Ȁɯ̛͈Ȁ̫ Gravatar ؈ěĉŪ˼Ċȏȁɽ̛̫ȀÓďĴɣƮ²ϥ ul ʜͭ ŠR̀ 9.25 ȁ͈ĴR̀ 9.25 ǻƯ»5 7.6 ωΌ1 R̀ 7.30 ̫ǺʔŠЄċ Gravatar ƣÍɟ˓`‘ͩ9ìɕȦŲ ؈̫œƄŠʔl*Àˎɽ‚їΌ1ӄĴΚΛҘЙ*ÀИì˽R̀ 7.30 ɹɞ Users ȸ¼ĩ̫ƣÍɟ˓ɘV R̀ 9.25 ̛Ȁ²ϥҹҷ̫ϱij app/views/users/index.html.erb <% provide(:title, 'All users') %>

All users

    <% @users.each do |user| %>
  • <%= gravatar_for user, size: 52 %> <%= link_to user.name, user %>
  • <% end %>
ǻUŸ˦Ê A CSSɹ͆°̫Зɮ SCSSΨÔ ŠR̀ 9.26 R̀ 9.26 ̛Ȁ²ϥҹҷ̫ CSS app/assets/stylesheets/custom.css.scss . . . /* Users index */ .users { list-style: none; margin: 0; li { 329 overflow: auto; padding: 10px 0; border-top: 1px solid $grayLighter; &:last-child { border-bottom: 1px solid $grayLighter; } } } ɼĊǻUіϬĴŘѸ̫ƀτ ʑ»̛Ȁ²ϥҹҷ̫҈ȷ҈ȷ̫ĵĸ$ users_pathїɮϥʣ 7.1 іˎK Α̫ɼĊ ™ĉм̜5̷ư̫˜ЍR̀ 9.27ě͘ƮȁҲ̫R̀R̀ 9.28ѹNjͮÞ R̀ 9.27 ʨ˜“Users”҈ȷ̫˜Ѝ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "with valid information" do let(:user) { FactoryGirl.create(:user) } before { sign_in user } it { should have_title(user.name) } it { should have_link('Users', href: users_path) } it { should have_link('Profile', href: user_path(user)) } it { should have_link('Settings', href: edit_user_path(user)) } it { should have_link('Sign out', href: signout_path) } it { should_not have_link('Sign in', href: signin_path) } . . . end end end R̀ 9.28 ˦Ê“Users”҈ȷ app/views/layouts/_header.html.erb πʶ̛Ȁ²ϥҹҷ̫ÉιƊų̓5ȁɽ̫˜Ѝ0ѹþTѫѐ5 $ bundle exec rspec spec/ ѐŠij 9.8 ȁ͈ҹҷ üɯ͈5 ̛Ȁɽ˸ŬÞÞҷϽǻUʌɌõ ї͑ǦǬ̉¥ 9.3.2 ā.ö® ĴʄƄω ǻUϬ$ư̛͘Ʈ˦ÊɹƠ̫̋ȀŠʔϬϽ̛Ȁ²ϥ̺눲ϥǻUþTĴ˝ϲĩ Їҕ˕ žҹҷ˼Ċ  ĵ˕ž̛Ȁѐіɽɹş̫ɟ˓Ͻ Ruby ě Rake $ǻUµƶ̛Ȁ ӊǻUϬĴ Gemfile ʑ fakerŠR̀ 9.29 ȁ͈n̛ї gemǻUþTn̛È̻ų̫ĉŪě Email ĵĸµƶ͈ơȀ R̀ 9.29 ȏ faker ʑ Gemfile source 'https://rubygems.org' ruby '2.0.0' #ruby-gemset=railstutorial_rails_4_0 331 gem 'rails', '4.0.0' gem 'bootstrap-sass', '2.3.2.0' gem 'bcrypt-ruby', '3.0.1' gem 'faker', '1.1.2' . . . ij 9.8 ̛Ȁ²ϥҹҷüɽ ̛Ȁ ˼Ċě*À ʠѓϡҷ̫ĚSůϪ $ bundle install ȷʌǻUϬ˦Ê  Rake X˵ƶ͈ơȀї Rake XËwūĴ lib/tasks ɘVř ήĴ :db Ěĉ͝ Җ Ų)ŠR̀ 9.30 ȁ͈R̀ ˠî» AӑΈ̾Љ̓Ĵǐˤ‘5ϵ R̀ 9.30 ĴɕȰƯ ̚Ǻ͈ơȀ̫ Rake XË lib/tasks/sample_data.rake namespace :db do desc "Fill database with sample data" 332 task populate: :environment do User.create!(name: "Example User", email: "example@railstutorial.org", password: "foobar", password_confirmation: "foobar") 99.times do |n| name = Faker::Name.name email = "example-#{n+1}@railstutorial.org" password = "password" User.create!(name: name, email: email, password: password, password_confirmation: password) end end end ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ij 9.9 ɯ͈5 100 ̛Ȁ̛̫Ȁ²ϥҹҷ/users ѝR̀Ų)5 ĉ$ db:populate ̫ Rake Xˍµƶ ̛ȀɻR*ÀūĴ̫Ѷ̛Ȁ˼Ċіµƶ5 99 ̛ȀҷїϡR̀ 333 task populate: :environment do ͆wї Rake XËþTϓó Rails ̒Ň̫xǠÓȠ User ʬľȁTȃιn̛ User.create! ɟ˓create! ɟ˓ě create ɟ˓̫k̛ ʠüѐŠʔȼp̫xǠć˓_ѕĬ false ήɮ_Ȓ¬ƸƤìϮ 6.1.4 ωїʠŠʔ¬Ҍ̫ЏƊNjŹɫȌ»ҌЕò̫̚ĵɟ їXËɮŲ)Ĵ :db Ěĉ͝Җ ̫ȁTǻUϬȧ˽Š̫ɟƻʌȆϡ $ bundle exec rake db:reset $ bundle exec rake db:populate $ bundle exec rake test:prepare ȆϡїXË*ĊǻU̫ư̛͘ƮƊɽ 100 ̛Ȁ5Šij 9.9 ȁ͈ǻ̇̅5 ˸GɩҖ$À©̛Ȁ `5؈їʠƊѹ_ɯ͈әϻ̫ Gravatar ؈5 9.3.3 BŲ ̓Ĵǃ¶̛̫ȀŸŬÞÞ5cɮí¬̓5ɞ̫ҕӄ ̛ȀŕŐ’Ĵ ҹҷ ɯ͈̓Ĵ̛̫ȀɕҀɮ 100 ͯɮƅ̫5Ĵ̻ų̫Τͤ їɕҀþιɮTÚϹ̫$5ѵĴ ҹ ɯ͈ѐƠ̫̋ȀǻUþT n̛¯ҹÉι ҹüɯ͈ 30 ̛Ȁ Ĵ Rails ɽNjŐų̓¯ҹ̫ɟ˓ǻUϬn̛˜ ɼͮÞ0ɼŰĦ̫ý‚ will_paginateǻUϬn̛ will_paginate ě bootstrap-will_paginate ї gembootstrap-will_paginate ̫k̛ɮІΦ will_paginate n̛ Bootstrap ̫¯ҹʠƻyɌĊ̫ Gemfile ŠR̀ 9.31 ȁ͈ R̀ 9.31 Ĵ Gemfile ʑ will_paginate source 'https://rubygems.org' ruby '2.0.0' #ruby-gemset=railstutorial_rails_4_0 gem 'rails', '4.0.0' gem 'bootstrap-sass', '2.3.2.0' gem 'bcrypt-ruby', '3.0.1' gem 'faker', '1.1.2' gem 'will_paginate', '3.0.4' gem 'bootstrap-will_paginate', '0.0.9' . . . ˼ĊȆϡҷ̫ĚSůϪ $ bundle install ůϪĊlіϬѿđ Web ɿËĩ͆wǺÉÊцїɞ gem 334 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ĭ$ will_paginate ї gem n̛̫ώİNjƭȁTǻUǐ‚œҀ̫˜ЍüҲͮÞ̫˜Ѝ ƊþT5 ӊǻUϬʨ˜ҹҷ ɮčÓď  CSS class $ pagination ̫ div ‹΁ї‹΁Ɗɮ̜ will_paginate ̚Ǻ ̫˼ĊǻUϬʨ˜¯ҹ̫ͩ ҹ ɮčɯ͈ɽʵ̛̫͆Ȁ²ϥĴ˜Ѝ ǻUϬ̛» paginate ɟ˓͙Ċ_ ‚KΑ ě*À ʠǻUϬn̛ Factory Girl ̚Ǻ̛ȀcɮǻU͢ӋƊ_ѯ» ҕӄ ĭ$̛Ȁ̫ Email ĵĸǐҽɮġ ̫Ѷ(ǻUƊϬȂÌ̚Ǻ 30 ̛Ȁїþɮ VNjЫ8̫˘‰ήĴ˜Ѝ̛Ȁ²ϥɩ̛Ȁ̫ĉŪɼş 0 ʠƬş Factory Girl ə8Š͋ȼp5 sequence ɟ˓ʌϵ¤ї͑ҕӄĴR̀ 7.8 ǻUɮ̶ȷъ‘ ĉŪě Email ĵĸʌµƶӀʐV̫ FactoryGirl.define do factory :user do name "Michael Hartl" email "michael@example.com" password "foobar" password_confirmation "foobar" end end ̓ĴǻUϬn̛ sequence ɟ˓ο̵ƶ ΀²̫ĉŪě Email ĵĸ factory :user do sequence(:name) { |n| "Person #{n}" } sequence(:email) { |n| "person_#{n}@example.com"} . . . sequence ɟ˓þTȷô  Symbol Ͷľ̫ìɕžư»ƓǝoŠ :name˜ĊіþTк̽Ļɽ Ļ ìɕǻUƃ˜Ěĉ$ nFactoryGirl.create(:user) ɟ˓ȆϡǺÉĊĻìɕ_οÌňÊ 1ĭʶµƶ ̫ͩ ̛ȀĉŪ$“Person 1”Email ĵĸ$“person1@example.com” ͩ9̛Ȁ̫ĉŪ$ Person 2Email ĵ ĸ$“person2@example.com” qʶͶȹŰɗ̫R̀ŠR̀ 9.32 ȁ͈ R̀ 9.32 Ų) Factory Girl Ʈ² spec/factories.rb FactoryGirl.define do factory :user do sequence(:name) { |n| "Person #{n}" } sequence(:email) { |n| "person_#{n}@example.com"} password "foobar" password_confirmation "foobar" end end µƶ5ӀʐVƮ²ĊĴ˜Ѝ ƊþT̚Ǻ 30 ̛Ȁ5ї 30 ̛ȀƊþTC̚¯ҹ5 335 before(:all) { 30.times { FactoryGirl.create(:user) } } after(:all) { User.delete_all } ˕DZѝR̀n̛ before(:all) ͆wĴĻ ȁɽ˜ЍȆϡ*À ʭǝµƶ 30 ͈ơȀїɮžѬƴ‚̫ ^Ôĭ$ĴʗA΀Ι ʿ˜Ѝѹµƶ 30 ̛Ȁ_NjǶžư̫ǻUЛ̛ after(:all) ɟ˓Ĵ˜ЍΔʉ Ċ ʭǝ·Ҧȁɽ̛̫Ȁ R̀ 9.33 ʨ˜5ҹҷ ɮčÓďʵ̫͆ div ‹΁Tîɮčɯ͈5ʵ̛̫͆Ȁ˕DZǻUȏR̀ 9.23 ̫ User.all ȮǺ5 User.paginate(page: 1)їʠǻUȃιMɕȰƯ óĬͩ ҹ Ϭɯ̛͈̫ȀіϬ˕ DZ R̀ 9.33 n̛̫ before(:each) ɟ˓ɮě before(:all) ɟ˓̷ñ̫Ɉk R̀ 9.33 ˜Ѝ¯ҹ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do subject { page } describe "index" do let(:user) { FactoryGirl.create(:user) } before(:each) do sign_in user visit users_path end it { should have_title('All users') } it { should have_content('All users') } describe "pagination" do before(:all) { 30.times { FactoryGirl.create(:user) } } after(:all) { User.delete_all } it { should have_selector('div.pagination') } it "should list each user" do User.paginate(page: 1).each do |user| expect(page).to have_selector('li', text: user.name) end end end end . . 336 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ . end Ϭų̓¯ҹǻUϬĴ̛Ȁ²ϥҹҷ̫ϱij ʑ AR̀ĔЊ Rails Ϭ¯ҹɯ̛͈ȀήϬȏ index Ìk ̫ User.all ȮǺ̾ѱŠh¯ҹ̫ɟ˓ǻUĴϱij ʑ̆ʻ̫ will_paginate ɟ˓ŠR̀ 9.34 ȁ͈ ͙ĊǻU_̺»$H(ϬĴ̛Ȁ²ϥ̫ÀĊѹʑ¯ҹR̀ R̀ 9.34 Ĵ̛Ȁ²ϥϱij ʑ¯ҹ app/views/users/index.html.erb <% provide(:title, 'All users') %>

All users

<%= will_paginate %>
    <% @users.each do |user| %>
  • <%= gravatar_for user, size: 52 %> <%= link_to user.name, user %>
  • <% end %>
<%= will_paginate %> will_paginate ɟ˓ɽ˸Ƅ͋ŚĴ Users ȸ¼ĩ̫ϱij Ů_οÌſȌĉ$ @users ̫žП˼Ċɯ͈  ¯ҹƀτ҈ȷR̀ 9.34 ȁ͈̫ϱij̓Ĵіιʵ͆ɯ͈¯ҹĭ$̓Ĵ @users ̫~ɮѫѐ User.all ɟ˓ϓ ó̫ɮɕ΍ ή will_paginate ɟ˓ҲϬ̫ɮ ActiveRecord::Relation ͶžПwill_paginate ȼp̫ paginate ɟ˓ʵşþTѕĬ ActiveRecored::Relation ͶžП $ rails console >> User.all.class => Array >> User.paginate(page: 1).class => ActiveRecord::Relation paginate ɟ˓þTȷô  Hash Ͷľ̫ìɕҎ :page ̫~ȦŲͩ©ҹUser.paginate ɟ˓ʢȰ :page ̫~ ʭóĬ ΀²̛̫Ȁәϻ$ 30 ȁTͩ ҹɯ͈̫ɮͩ 1-30 ̛Ȁͩ9ҹɯ͈̫ɮͩ 31-60 ͪŠʔȦŲ̫ҹɕūĴpaginate _ɯ͈ͩ ҹ ǻUþTȏ index Ìk ̫ all ɟ˓ȮǺ paginateїʠҹҷ ƊþTɯ͈¯ҹƀτ5ŠR̀ 9.35 ȁ͈ paginate ɟ˓ȁҲ̫ :page ìɕ~̜ params[:page] ȦŲї params ‹΁ɮ̜ will_pagenate οÌ̚ Ǻ̫ R̀ 9.35 Ĵ index Ìk ȧ¯ҹóĬ̛Ȁ app/controllers/users_controller.rb 337 class UsersController < ApplicationController before_action :signed_in_user, only: [:index, :edit, :update] . . . def index @users = User.paginate(page: params[:page]) end . . . end ̓Ĵ̛Ȁ²ϥҹҷưВþTɯ͈¯ҹ5Šij 9.10 ȁ͈ĴʗA΀Ι þιҲϬѿđ Rails ɿËĩĭ$ ǻUĴ̛Ȁ²ϥÀĊѹʑ5 will_paginate ɟ˓ȁTїĵɟѹ_ɯ͈¯ҹ҈ȷ ij 9.10 ɯ͈5¯ҹ҈ȷ̛̫Ȁ²ϥҹҷ/users Šʔ˸­҈ȷ“2”Ǽέ“Next”Ɗ_ɯ͈ͩ9ҹŠij 9.11 ȁ͈ 338 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ij 9.11 ̛Ȁ²ϥ̫ͩ9ҹ/users?page=2 lіưВӎЈ ˜ЍɮčþTѫѐ $ bundle exec rspec spec/ 9.3.4 ijnŢ× ̛Ȁ²ϥҹҷ̓ĴƝΒþTɯ͈¯ҹ5cɮɽɌј˸ǻnjKΑ Rails ȼp5 ANjƚš̫ɟ˓þTͻ ͮϱij̫ΔʐʄƄωǻUƊϬ¹̛їAɟ˓ѿʐ ̛Ȁ²ϥҹҷĭ$ǻUƝΒ‚5Njş̫˜ЍȁTƊþT ɎȂëѿʐ̛ȘǏ_͂ĺΤ̫ͤÉι ѿʐ̫ͩ ʷϬȏR̀ 9.34 ̫ li ȮǺž render ɟ˓̫Л̛ŠR̀ 9.36 ȁ͈ R̀ 9.36 ѿʐ̛Ȁ²ϥϱij̫ͩ ʷ app/views/users/index.html.erb <% provide(:title, 'All users') %>

All users

<%= will_paginate %>
    339 <% @users.each do |user| %> <%= render user %> <% end %>
<%= will_paginate %> ĴѝR̀ render ̫ìɕŸɮȦŲƎѸϱij̫Ūͨ"ήɮRϥ User Ͷ̫ user õҀ6Rails _οŲſȌ ĉ$ _user.html.erb ̫ƎѸϱijǻUϬȂ̵ƶїϱij˼Ċ¢‘R̀ 9.37 ̫Ź R̀ 9.37 ɯ͈Þ ̛Ȁ̫ƎѸϱij app/views/users/_user.html.erb
  • <%= gravatar_for user, size: 52 %> <%= link_to user.name, user %>
  • їɌјNjҌѐǻUіþT‚̫ɹşǻUþT̶ȷȏ @users õҀ`ѨΖ render ɟ˓ŠR̀ 9.38 ȁ ͈ R̀ 9.38 ےѿʐĊ̛̫Ȁ²ϥϱij app/views/users/index.html.erb <% provide(:title, 'All users') %>

    All users

    <%= will_paginate %>
      <%= render @users %>
    <%= will_paginate %> Rails _ȏ @users ǃk ΀²̫ User žПѰèїAžП˼Ċn̛ _user.html.erb ˪ʘʿžПȁTǻ UƊnj»5R̀ 9.38 їʠͮ˖̫R̀ʿʭѿʐĊlѹưВӎЈ ˜Ѝ΍VɮčіɮþTѫѐ̫ $ bundle exec rspec spec/ 6. ǻUƫɮ ŲϬn̛ userѰèɩŠʔ̛̫ɮ @users.each do |foobar|Ѷ(ƊϬ̛ render foobarїѾ̫– ҎɮϬ̾ѱžП̫Ͷ0Ɗɮ User 340 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ 9.4 GŬö® πʶ̛Ȁ΂Ƽ0ŰǺ5ͨć REST ʖʐ̫Users ЬˬƊüÃɼĊ  destroy Ìk5ʄωǻU˦Ê· Ҧ̛Ȁ̫҈ȷʐǜijŠij 9.12 ȁ͈˼ĊŸΠ¢Ѣǃ̫ destroy ÌkR̀ŰǺ·ҦɈkѐӊǻUϬ µƶͰ̕ĕΈº̛̫ȀƫȲʈїA̛Ȁјϡ·ҦɈk ij 9.12 ɯ͈ɽ·Ҧ҈ȷ̛̫Ȁ²ϥҹҷʐǜij 9.4.1 čôf ǻUϬѫѐ User ʬľ ĉ$ admin ̫Ɠǝʌ¸ɜ̛Ȁɮč™ɽͰ̕ĕʈҤadmin Ɠǝ̫Ͷľ$ƞƆ~ Active Record _οÌ̚Ǻ  admin? ɟ˓ѕĬƞƆ~¸ɜ̛Ȁɮč$Ͱ̕ĕ҂ž admin Ɠǝ̫˜ЍŠR ̀ 9.39 ȁ͈ R̀ 9.39 ˜Ѝ admin Ɠǝ spec/models/user_spec.rb require 'spec_helper' 341 describe User do . . . it { should respond_to(:authenticate) } it { should respond_to(:admin) } it { should be_valid } it { should_not be_admin } describe "with admin attribute set to 'true'" do before do @user.save! @user.toggle!(:admin) end it { should be_admin } end . . . end ĴѝR̀ ǻUn̛ toggle! ɟ˓ȏ admin Ɠǝ̫~M false тõǺ trueit { should be_admin } їϡR̀Зɪ̛ȀžПưВþTĞư admin? ɟ˓їɮ RSpec žƞƆ~Ɠǝ̫ ·Ų ě*À ʠǻUϬn̛ю͗˦Ê admin ƓǝĴĚSϡ ȦŲ˜Ͷľ$ boolean $ rails generate migration add_admin_to_users admin:boolean їĚS̚Ǻ̫ю͗ɘVŠR̀ 9.40 ȁ͈_Ĵ users ϥ ˦Ê admin ї ²nj»̫ɕȰʬľŠij 9.13 ȁ ͈ ij 9.13 ˦Ê5 admin ƓǝĊ̫ User ʬľ R̀ 9.40 $ User ʬľ˦Ê admin Ɠǝȁ̛̫ю͗ɘV db/migrate/[timestamp]_add_admin_to_users.rb class AddAdminToUsers < ActiveRecord::Migration def change 342 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ add_column :users, :admin, :boolean, default: false end end ˕DZĴR̀ 9.40 ǻU$ add_column ɟ˓ȦŲ5 default: false ìɕ˦ÊїìɕĊ̛Ȁәϻǧ¥ ƊɮͰ̕ĕŠʔˎɽȦŲ default: falseadmin ̫әϻ~ɮ nil0ɮ“€~”ȁTʣʌЗї ìɕɮǐҽ̫ѐȦŲїìɕþTɹɪ͆ĵċ Rails TîR̫̀ҘЙέϥɪїʼR̫̀DZij ˼ĊǻUϬĴ“ƷòɕȰƯ” Ȇϡю͗ɈkіϬ¦ōş“˜ЍɕȰƯ” $ bundle exec rake db:migrate $ bundle exec rake test:prepare ěӀǯ̫ ʠRails þTοÌЉº admin Ɠǝ̫Ͷľ$ƞƆ~ήοÌ̚Ǻ5 admin? ɟ˓ $ rails console --sandbox >> user = User.first >> user.admin? => false >> user.toggle!(:admin) => true >> user.admin? => true Ȇϡю͗ɈkĊ҂ž admin Ɠǝ̫˜ЍưВþTѫѐ5 $ bundle exec rspec spec/models/user_spec.rb ɼĊǻUϬyɌ ̚Ǻ͈ơȀ̫R̀ȏͩ ̛ȀІ$Ͱ̕ĕŠR̀ 9.41 ȁ͈ R̀ 9.41 ̚Ǻ͈ơȀ̫R̀ȏͩ ̛ȀІ$Ͱ̕ĕ lib/tasks/sample_data.rake namespace :db do desc "Fill database with sample data" task populate: :environment do admin = User.create!(name: "Example User", email: "example@railstutorial.org", password: "foobar", password_confirmation: "foobar", admin: true) . . . end end 343 *ĊіϬіêɕȰƯƫѿɞ̚Ǻ͈ơȀ $ bundle exec rake db:reset $ bundle exec rake db:populate $ bundle exec rake test:prepare “4wVÇ”?º lþι˕DZ»5ĴR̀ 9.41 ǻUĴ¶ţÔ Hash ìɕ ȦŲ5 admin: true ơ̑ȀІ$Ͱ̕ĕї(‚̫ Ċʔɮ̛ȀžПɷҳĴΤΗ 5ŠʔĴИˇ ȼp¶ţÔìɕǢDZ̛ȀƊþTòѡŠ̫ PATCH Иˇ7 patch /users/17?admin=1 їИˇ_ȏ 17 Ă̛ȀІ$Ͱ̕ĕїǚ(З0ɮ˳Ĵ̫ů’ҪǤ ҁ:ʶǐҽüŠЄ`‘þů’Πщ̫ƓǝǻUĴ 7.3.2 ω ЗѐþTn̛“„Ŋìɕ”Ĵ params Hash Л ̛ require ě permit ɟ˓ def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end ˕DZadmin ƫĴŠЄn̛̫Ɠǝ²ϥ їʠƊþTѵ̛ȀónjΤ̫ͤͰ̕ʈĭ$ї ʷNjѿϬɼşŸ ˜Ѝ ĆƓǝɮčɮþЇҕ̫ž :admin Ɠǝ̫þЇҕǝ˜Ѝ̢kΌ1ìϮ 9.6 ω 9.4.2 destroy M, Π¢Űɗ̫ Users ЬˬіϬŸ˦Ê·Ҧ҈ȷě destroy ÌkǻUĴ̛Ȁ²ϥҹҷʿ̛ȀĊҷѹʑ · Ҧ҈ȷήҤ¼üɽͰ̕ĕȃι̺»їA҈ȷ Π¢҂ž·ҦÉι̫˜ЍɼşιɽµƶͰ̕ĕ̫Ƙçɟ˓$ʶǻUþTĴӀʐV ʑ ĉ$ :admin ̫ĻŠR̀ 9.42 ȁ͈ R̀ 9.42 ˦Ê µƶͰ̕ĕ̫Ƙçɟ˓ spec/factories.rb FactoryGirl.define do factory :user do sequence(:name) { |n| "Person #{n}" } sequence(:email) { |n| "person_#{n}@example.com"} password "foobar" password_confirmation "foobar" 7. Ͷb curl ̫ĚSϡƘ™þTòѡї͑ PATCH Иˇ 344 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ factory :admin do admin true end end end ˦Ê5TR̀*ĊǻUƊþTĴ˜Ѝ Л̛ FactoryGirl.create(:admin) µƶͰ̕ĕ̛Ȁ5 Ń:ů’άϛɱѫ̛Ȁɮ̺»·Ҧ̛Ȁ҈ȷ̫ȁT it { should_not have_link('delete') } üɽͰ̕ĕȃι̺»·Ҧ̛Ȁ҈ȷŠʔͰ̕ĕ˸­5·Ҧ̛Ȁ҈ȷВ̛Ȁ_ϧ·Ҧ̛Ȁ̫ɕҀƊ_§ƅ 1  it { should have_link('delete', href: user_path(User.first)) } it "should be able to delete another user" do expect do click_link('delete', match: :first) end.to change(User, :count).by(-1) end it { should_not have_link('delete', href: user_path(admin)) } ѝR̀ ̛»5 match: :firstїìɕĔ̾ CapybaraͰɮĠ·Ҧ҈ȷü˸­ͩ ̺»̫˕ DZǻUі˦Ê5 ˜Ѝ͆wͰ̕ĕ_̺»·ҦοƜ̫҈ȷ҂ž·Ҧ̛Ȁ̫Űɗ˜ЍŠR̀ 9.43 ȁ͈ R̀ 9.43 ˜Ѝ·Ҧ̛ȀÉι spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do subject { page } describe "index" do let(:user) { FactoryGirl.create(:user) } before do sign_in user visit users_path end it { should have_title('All users') } it { should have_content('All users') } 345 describe "pagination" do . . . end describe "delete links" do it { should_not have_link('delete') } describe "as an admin user" do let(:admin) { FactoryGirl.create(:admin) } before do sign_in admin visit users_path end it { should have_link('delete', href: user_path(User.first)) } it "should be able to delete another user" do expect do click_link('delete', match: :first) end.to change(User, :count).by(-1) end it { should_not have_link('delete', href: user_path(admin)) } end end end . . . end ˼ĊĴϱij ʑR̀ 9.44˕DZ҈ȷ ̫ method: delete ìɕŮȦɪ˸­҈ȷĊòѡ̫ɮ DELETE Иˇ ǻUіȏĆ҈ȷɎĴ5 if Дú їʠƊüɽͰ̕ĕȃι̺»·Ҧ̛Ȁ҈ȷͰ̕ĕ̺»̫ҹҷŠij 9.14 ȁ͈ R̀ 9.44 ·Ҧ̛Ȁ̫҈ȷüɽͰ̕ĕȃι̺» app/views/users/_user.html.erb
  • <%= gravatar_for user, size: 52 %> <%= link_to user.name, user %> <% if current_user.admin? && !current_user?(user) %> | <%= link_to "delete", user, method: :delete, data: { confirm: "You sure?" } %> 346 <% end %>
  • ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ij 9.14 ɯ͈ɽ·Ҧ̛Ȁ҈ȷ̛̫Ȁ²ϥҹҷ/users ˝ϲĩιòѡ DELETE ИˇRails ѫѐ JavaScript јϡʬȝ̫0ƊɮЗŠʔ̛Ȁ̛͌5 JavaScriptѶ(· Ҧ̛Ȁ̫҈ȷƊþ̛5ŠʔǐҽϬɊȥˎɽđ̛ JavaScript ̫˝ϲĩlþTn̛ òѡ POST Иˇ̫ϥÞ ʌʬȝ DELETE Иˇїʠån˝ϲĩ̫ JavaScript ϧ̛͌5·Ҧ̛Ȁ̫҈ȷіɮþ̛̫ɹŐΎωИϯ̺ RailsCasts ͩ 77 үDestroy Without JavaScript ϋϬ·Ҧ̛Ȁ̫҈ȷгk̛ǻUϬŲ) destroy ÌkìϮϥʣ 7.1Ĵ destroy Ìk Ȍ»Ϭ·Ҧ̫ ̛Ȁn̛ Active Record ȼp̫ destroy ɟ˓·Ҧї̛Ȁ˼ĊŸтċ̛Ȁ²ϥҹҷŠR̀ 9.45 ȁ͈ R̀ 9.45 ʑ destroy Ìk app/controllers/users_controller.rb class UsersController < ApplicationController before_action :signed_in_user, only: [:index, :edit, :update, :destroy] before_action :correct_user, only: [:edit, :update] . . . def destroy 347 User.find(params[:id]).destroy flash[:success] = "User destroyed." redirect_to users_url end . . . end ˕DZѝ destroy Ìk ȏ find ɟ˓ě destroy ɟ˓҈Ĵ гn̛5 User.find(params[:id]).destroy ̕ЅüɽͰ̕ĕȃι̺»·Ҧ̛Ȁ̫҈ȷȁTüɽͰ̕ĕȃι·Ҧ̛ȀcųҠіɮūĴ ѿ̫ů ’ҪǤ üϬɍ­έɽзŒ̫ΒӎƊþTĴĚSϡ òѡ DELETE Иˇ·ҦΤͤ ̛̫Ȁ$5wЈΤ̫ͤů ’ǻUіϬҤ¼ž destroy Ìk̫ЇҕĭʶǻUĴ˜Ѝ IϬ͆wüɽͰ̕ĕȃι·Ҧ̛ȀіϬwЈ˜ P̛ȀιȆϡ·ҦɈkŠR̀ 9.46 ȁ͈˕DZěR̀ 9.11 ̫ put ɟ˓ͶbĴїʼR̀ ǻUn̛ delete ɟ˓ċȦŲ̫ĵĸuser_pathìϮϥʣ 7.1òѡ5  DELETE Иˇ R̀ 9.46 ˜ЍЇҕôҤ̫ destroy Ìk spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do . . . describe "as non-admin user" do let(:user) { FactoryGirl.create(:user) } let(:non_admin) { FactoryGirl.create(:user) } before { sign_in non_admin, no_capybara: true } describe "submitting a DELETE request to the Users#destroy action" do before { delete user_path(user) } specify { expect(response).to redirect_to(root_path) } end end end end 348 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ ̕ЅʌЗΤͤ іɮɽ ů’˱˗Ͱ̕ĕþTòѡ DELETE Иˇ·ҦοƜɽAGþι_ǯїʠ̫Ͱ̕ ĕɮοkοôѐk$ƷòGĕǻUɼşіɮϬѵї͑ǧ¥̫ò̚™g̫ų̢̓kΌ1ìϮ 9.6 ω lþιƝΒ̾ѱ5ǻUϬn̛ 8Àѐ˰ĩҤ¼ž destroy Ìk̫ЇҕŠR̀ 9.47 ȁ͈ R̀ 9.47 Ҥ¼üɽͰ̕ĕȃιЇҕ destroy Ìk̫8Àѐ˰ĩ app/controllers/users_controller.rb class UsersController < ApplicationController before_action :signed_in_user, only: [:index, :edit, :update, :destroy] before_action :correct_user, only: [:edit, :update] before_action :admin_user, only: :destroy . . . private . . . def admin_user redirect_to(root_path) unless current_user.admin? end end πʶȁɽ̫˜ЍưВѹþTѫѐ5ή Users ̷–̫ЬˬÓȠȸ¼ĩʬľěϱijѹƝΒų̓5 $ bundle exec rspec spec/ 9.5 ŒĘ ǻƯ5ş©ͥʌKΑŠhų̓ Users ЬˬĴ 5.4 ω̛Ȁіι˕žή̓ĴIþT˕žіþT̨DŽѠ ¬ʙ̺GЬəyɌІΦіι˝ϲΤͤ ȁɽ̛̫Ȁ²ϥʗA̛Ȁ̙πþT·Ҧ˜P̛̫Ȁ ʄ2Ã̫Ź_Tї Users Ьˬ$Ń̈́Tî̷–̫ʈҤȲʈ΀ΙĴͩ 10 ͥ $͈o͘ƮʑͶb Twitter ̫ǎàÉιĴͩ 11 ͥ ų̓–˕̛Ȁ̫̉Ǚ²ϥɼĊїͥ_KΑ© Rails ɼ$ǁœ̫Éι˜ ƊÓȠѫѐ has_many ě has_many through ų̫̓ɕȰʬľ–γ ĴΚΛҘЙ*Àȏʄͥȁ‚̫ɌÌćƫ»%¯Ɋ $ git add . $ git commit -m "Finish user edit, update, index, and destroy actions" $ git checkout master $ git merge updating-users lіþTƃ͘ƮѸΧ»“̚C̒Ň”Ÿ̚Ǻ͈ơȀĴʶ*ÀϬn̛ pg:reset ĚSіê“̚CɕȰƯ” 349 $ git push heroku $ heroku pg:reset DATABASE $ heroku run rake db:migrate $ heroku run rake db:populate ϋϬɌÌɯ͈¬ʌþιϬĴ Heroku ǁ¼ѿđư̛͘Ʈ $ heroku restart іɽ ˸ҲϬ˕DZʄͥǻUʑ5͘ƮȁҲ̫ɼĊ  gemɼΐ̫ Gemfile ŠR̀ 9.48 ȁ͈ R̀ 9.48 ͈o͘ƮȁҲ Gemfile ̫ɼΐ̂ʄ source 'https://rubygems.org' ruby '2.0.0' #ruby-gemset=railstutorial_rails_4_0 gem 'rails', '4.0.0' gem 'bootstrap-sass', '2.3.2.0' gem 'bcrypt-ruby', '3.0.1' gem 'faker', '1.1.2' gem 'will_paginate', '3.0.4' gem 'bootstrap-will_paginate', '0.0.9' group :development, :test do gem 'sqlite3', '1.3.7' gem 'rspec-rails', '2.13.1' # The following optional lines are part of the advanced setup. # gem 'guard-rspec', '2.5.0' # gem 'spork-rails', github: 'sporkrb/spork-rails' # gem 'guard-spork', '1.5.0' # gem 'childprocess', '0.3.6' end group :test do gem 'selenium-webdriver', '2.0.0' gem 'capybara', '2.1.0' gem 'factory_girl_rails', '4.2.0' gem 'cucumber-rails', '1.3.0', :require => false gem 'database_cleaner', github: 'bmabey/database_cleaner' # Uncomment this line on OS X. # gem 'growl', '1.0.3' # Uncomment these lines on Linux. # gem 'libnotify', '0.8.0' 350 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ # Uncomment these lines on Windows. # gem 'rb-notifu', '0.0.4' # gem 'win32console', '1.3.2' end gem 'sass-rails', '4.0.0' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.0' gem 'jquery-rails', '2.2.1' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' group :doc do gem 'sdoc', '0.3.20', require: false end group :production do gem 'pg', '0.15.1' gem 'rails_12factor', '0.0.2' end 9.6 Ė 1. ì˽R̀ 9.49̶ȷċ update Ìkòг PATCH ИˇӎЈ ɣ˓yɌ admin Ɠǝ͆w˜ЍɮΆ χ̫˼Ċȃ_õΝȼ͈ Ϭȏ admin ʑ user_params ɟ˓̫ŠЄЇҕƓǝ²ϥ  2. ȏR̀ 9.3 yɌ Gravatar ؈̫҈ȷ“change”n҈ȷĴɞ͠øǼɞʜͭ ȄƷȼ͈ Иȿ ΂l_ò̓ NjƤ̛̫ɟ˓ˠî» _blank ̛̫˓ 3. ̓Ĵ҂žсYӎЈ΀Ι̫˜Ѝ_͆w̛Ą̏DŽĊι̺»“Profile”ě“Settings”ͪƀτ҈ȷňÊ ˜Ѝ ͆w̛Ȁʂ̨DŽɩ̺»їAƀτ҈ȷ 4. Ĵ˜Ѝ ƌҀŐ̫n̛R̀ 9.6 ̫ sign_in ƣÍɟ˓ 5. n̛R̀ 9.50 ̫R̀ѿʐ new.html.erb ě edit.html.erb ̫ϥÞ˕DZlϬɪ̫͆`‘ f ї ϥÞõҀŠR̀ 9.51 ȁ͈lіϬyɌ̷ư̫˜Ѝĭ$ϥÞƝΒے ʠ5OΎ̫ʙȌyɌÀ ĊϥÞ̫ƛƸȰʶyɌ˜Ѝ 6. ƝΒ̨DŽ̛̫ȀƊˎǐϬŸЇҕ Users ȸ¼ĩ̫ new ě create Ìk5yɌ͘ƮŠʔ̨DŽĊ̛̫ȀЇ ҕїAĵĸɩтċ»Τͤӊҹ 7. ĴΤ̫ͤƞƎ Ƚ‘ A Rails API KΑ̫ɟ˓5ϵ  request žПŠʔѯ»5įҭþTì άR̀ 7.1 351 8. Π¢ ˜Ѝ͆wïşтċüĴͩ ʭтċȦŲ̫ĵĸ˜ĊŸ̨DŽ̫ЏƊтċәϻІŲ̫ĵĸŠЬ əҹҷR̀ 9.52 ɮȼ͈˜ų0ƊɮȁҲ̫R̀ 9. yɌ destroy ÌkѵͰ̕ĕ·ҦοƜΠ¢˜Ѝ R̀ 9.49 ˜Ѝ admin Ɠǝɮčɣ˓yɌ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . . . describe "edit" do . . . describe "forbidden attributes" do let(:params) do { user: { admin: true, password: user.password, password_confirmation: user.password } } end before { patch user_path(user), params } specify { expect(user.reload).not_to be_admin } end end R̀ 9.50 ˕žěΠщϥÞŪʼ̫ƎѸϱij app/views/users/_fields.html.erb <%= render 'shared/error_messages' %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :email %> <%= f.text_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirm Password" %> <%= f.password_field :password_confirmation %> R̀ 9.51 n̛ƎѸϱijĊ̫˕žҹҷϱij app/views/users/new.html.erb 352 ͩ 9 ͥ ɹɞɯ͈ě·Ҧ̛Ȁ <% provide(:title, 'Sign up') %>

    Sign up

    <%= form_for(@user) do |f| %> <%= render 'fields', f: f %> <%= f.submit "Create my account", class: "btn btn-large btn-primary" %> <% end %>
    R̀ 9.52 ˜Ѝïş̫тċĊüιтċ»әϻ̫ҹҷ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do describe "for non-signed-in users" do . . . describe "when attempting to visit a protected page" do before do visit edit_user_path(user) fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Sign in" end describe "after signing in" do it "should render the desired protected page" do expect(page).to have_title('Edit user') end describe "when signing in again" do before do delete signout_path visit signin_path fill_in "Email", with: user.email 353 fill_in "Password", with: user.password click_button "Sign in" end it "should render the default (profile) page" do expect(page).to have_title(user.name) end end end end end . . . end end 354 ͩ 10 ͥ ̛Ȁ̫ǎà ĉ 10 ć ö®û¦S ǻUĴͩ 9 ͥ ƝΒų̓5 Űɗͨć REST ʖʐ̫Ьˬ ̛ȀʄͥǻUϬŸų̓ Ьˬ ̛Ȁǎà micropost1ǎàɮ̛̜Ȁòƞ̫ ͑ͮ̿˟ǠǻUĴͩ 2 ͥ ų̓5ǎà̫ҰDž ʄͥǻU_Ĵ 2.3 ω̫Ń ̈́ų̓ ÉιŰĦ̫ Microposts ЬˬӊǻUϬµƶǎàȁҲ̫ɕȰʬľѫѐ has_many ě belongs_to ɟ˓ȏǎàě̛Ȁ–γгʌŸƶ͢Ō̕ěɯ͈ǎàȁҲ̫ϥÞîƎѸϱijĴ ͩ 11 ͥіϬʑ –˕˜P̛Ȁ̫Éι˜ɩǻUїƔŽ̂ Twitter ȃͯŰǺ Šʔln̛ Git ‚̂ʄȸ¼̫Џě*À ʠǻƶϿlɞƶ ¯Ɋ $ git checkout -b user-microposts 10.1 Microposts às ų̓ Microposts Ьˬ̫ͩ ʷɮµƶǎàȁҲ̫ɕȰʬľĴʬľ ІŲǎà̫ŃʄƓǝě 2.3 ω µƶ̫ʬľͶ bǻUϬų̫̓ Micropost ʬľϬÓďɕȰӎЈTîě User ʬľ̫–γҦʶ*ŏǻUі_‚Œ¯̫˜Ѝ ȦŲәϻ̫ȵƮɟƻοÌ·ҦƝ˕҉̛Ȁ̫ǎà 10.1.1 uÓàs Micropost ʬľüҲϬƓǝ ɮ content̛ʌwūǎà̫Ź 2û ɮ user_idȏǎàě̛Ȁ– γгʌǻUϬn̛ generate model ĚS̚ǺȁҲ̫ʬľї ˸ěµƶ̛Ȁʬľɩɮ ʠ̫ìϮR̀ 6.1 $ rails generate model Micropost content:string user_id:integer їĚSɽþι_̚Ǻ ǎàӀʐVlưВȏŮ·ȳĭ$ĊҷǻU_οƜΠ¢ȁҲ̫ӀʐVìϮ10.1.4 ω $ rm -f spec/factories/microposts.rb ѝĚS_̚Ǻ ю͗ɘVĴɕȰƯ ̚Ǻ ĉ$ microposts ̫ϥìϮR̀ 10.1ЙέɾïþTě ̚Ǻ users ϥ̫ю͗ɘVž˽ ìϮR̀ 6.2 R̀ 10.1 µƶǎàʬľ̫ю͗ɘV˕DZ $ user_id ě created_at ²Ê‘5΂Ƽ db/migrate/[timestamp]_create_microposts.rb 1. ʣʌЗǻUĴͩ 8 ͥ ɮȏ session ǃ‚ЬˬʌŌ̫̕ѐ session _ˆ Users ě Microposts ЬˬѶʠϧū‘ɕȰƯ 2. content ƓǝɮŪͨ"stringͶľѐǻUɺĴ 2.1.2 ω ͮϬKΑѐчґ̫ɘʄưВn̛ text Ͷľ 355 class CreateMicroposts < ActiveRecord::Migration def change create_table :microposts do |t| t.string :content t.integer :user_id t.timestamps end add_index :microposts, [:user_id, :created_at] end end ˕DZĭ$ǻUІǯϬȧ˽òƞɩҖ̫zƮʙБʗ̛Ȁȁɽ̫ǎàȁTĴѝR̀ $ user_id ě created_at ²Ê‘5΂Ƽ add_index :microposts, [:user_id, :created_at] ǻUȏ user_id ě created_at ɎĴ ɕ΍ ĔЊ Rails ǻUϬµƶ̫ɮ“ŐҎ΂Ƽmultiple key index” Active Record t_Ĉɩn̛їҎіϬ˕DZ t.timestamps їϡǻUĴ 6.1.1 ω KΑѐŮ_ο̵ƶ created_at ě updated_at ƓǝĴ 10.1.4 ω ě 10.2.1 ω ȃ_̛» created_at ǻUì˽ User ʬľ̫˜Ѝì˽R̀ 6.5$ Micropost ʬľΠ¢ AŃʄ̫˜ЍǻUϬ˜ЍǎàžПɮč þTĞư content ě user_id ɟ˓ŠR̀ 10.2 ȁ͈ R̀ 10.2 Micropost ʬľ˜Ѝ¶ţ̂ spec/models/micropost_spec.rb require 'spec_helper' describe Micropost do let(:user) { FactoryGirl.create(:user) } before do # This code is not idiomatically correct. @micropost = Micropost.new(content: "Lorem ipsum", user_id: user.id) end subject { @micropost } it { should respond_to(:content) } it { should respond_to(:user_id) } end ϋϬї˜ЍѫѐǻUϬȆϡɕȰƯю͗Ÿ¦ōş“˜ЍɕȰƯ” 356 $ bundle exec rake db:migrate $ bundle exec rake test:prepare ȆϡҷĚS*Ċ_̚Ǻ Micropost ʬľΔʐŠij 10.1 ȁ͈ ͩ 10 ͥ ̛Ȁ̫ǎà ˼Ċ͆ϻ˜ЍɮčþTѫѐ ij 10.1 Micropost ɕȰʬľ $ bundle exec rspec spec/models/micropost_spec.rb ˜Ѝϝ˼þTѫѐѐlþι˕DZ»R̀ 10.2 ̫ї©ϡR̀5 let(:user) { FactoryGirl.create(:user) } before do # This code is not idiomatically correct. @micropost = Micropost.new(content: "Lorem ipsum", user_id: user.id) end Ɗˆ˜ ̫˕ѽȁЗbefore Ļ ̫R̀ƫےʵ͆lþTǯ $H(ǻU_Ĵ 10.1.3 ω ĔЊlͫ ʥ 10.1.2 ĉÇ·źľ Micropost ʬľǐҽϬɽ Ɠǝϥɪ̛Ȁ̫ IDїʠȃι̾ѱɮĠ̛Ȁòƞ̫ǎàϬʑїƓǝɼş̫ ɟ˓ɮn̛ Active Record –γ_Ĵ 10.1.3 ωų̓ų̫̓ѐ͘ҲϬ ˸ѿʐʄωǻUƊΠ¢ ˜ЍȬϓþι ¬̫̓ҌЕ ˜ЍŠR̀ 10.3 ȁ͈ǻUơ̑Ȁ ID І$ nil˼Ċʨ˜žư̫ǎàɮčć˓þTěR̀ 6.8 ҂ž User ʬľ̫˜Ѝžˀ  R̀ 10.3 ˜ЍǎàιčѫѐӎЈ spec/models/micropost_spec.rb require 'spec_helper' describe Micropost do let(:user) { FactoryGirl.create(:user) } before do # This code is not idiomatically correct. 357 @micropost = Micropost.new(content: "Lorem ipsum", user_id: user.id) end subject { @micropost } it { should respond_to(:content) } it { should respond_to(:user_id) } it { should be_valid } describe "when user_id is not present" do before { @micropost.user_id = nil } it { should_not be_valid } end end їʼR̀˜Ѝ5ǎàɮčιŒѫѐӎЈTîɮčȦŲ5 user_id ̫~ϬǯϽѝ˜ЍѫѐǻUϬȧ˽R̀ 10.4 ȁ͈ʑ ͮÞ̫ūĴǝӎЈ R̀ 10.4 žǎà user_id Ɠǝ̫ӎЈ app/models/micropost.rb class Micropost < ActiveRecord::Base validates :user_id, presence: true end 10.1.3 ö®h¦SŪû:ĥ Ĵ$ Web ͘ƮʐƶɕȰʬľɩɼŃʄ̫άϛϬ΁ɮϬιŒĴĈ̫ʬľ*Җƶ͢–γĴǻUї͘Ʈ ʿͳ ǎàѹ–γ̽ ̛Ȁήʿ̛Ȁ υѹ_–γŐͳǎà̛Ȁěǎà*Җ̫–΀Ĵ 2.3.3 ω ͮÞ̫KΑѐ 9έ*Җ̫–΀Šij 10.2 ěij 10.3 ȁ͈Ĵų̓ї͑–γ̫ɩ|ǻU_Π¢҂ž Micropost ʬľ̫˜Ѝі_Π ¢҂ž User ʬľ̫˜Ѝ ij 10.2 ǎàě̛Ȁ*Җ̫“Ɠ:belongs_to”–΀ 358 ͩ 10 ͥ ̛Ȁ̫ǎà ij 10.3 ̛Ȁěǎà*Җ̫“ȞɽŐhas_many”–΀ n̛ʄƄωKΑ̫ belongs_to ě has_many *ĊRails _ο̵ƶŠϥʣ 10.1 ȁ͈̫ɟ˓ ϥʣ 10.1 ̛Ȁěǎà–γĊȁnjɟ˓̫ͮK ɟ˓ k̛ micropost.user ѕĬВǎàžư̛̫ȀžП user.microposts ѕĬВ̛Ȁ̫ȁɽǎàɕ΍ user.microposts.create(arg) µƶ ͳǎàuser_id = user.id user.microposts.create!(arg) µƶ ͳǎàŗХɩȒ¬ƸƤ user.microposts.build(arg) ̚Ǻ ɞ̫ǎàžПuser_id = user.id ˕DZMϥʣ 10.1 þ̷̾ч:T̫ɟ˓ Micropost.create Micropost.create! Micropost.new ǻUnj»5 user.microposts.create user.microposts.create! user.microposts.build Ċέȃɮµƶǎà̫ʵ͆ɟƻåѫѐ̷–γ̛̫ȀžПµƶѫѐї͑ɟƻµƶ̫ǎà˜ user_id Ɠǝ_ο ÌІ$ʵ̫͆~ȁTǻUþTȏR̀ 10.3 ̫ѝR̀ 359 let(:user) { FactoryGirl.create(:user) } before do # This code is not idiomatically correct. @micropost = Micropost.new(content: "Lorem ipsum", user_id: user.id) end yɌ$ let(:user) { FactoryGirl.create(:user) } before { @micropost = user.microposts.build(content: "Lorem ipsum") } üϬʵ͆Ų)5̛Ȁěǎà*Җ̫–γ–΀@micropost õҀ̫ user_id ƓǝƊ_οÌІ$̷žư̛Ȁ̫ id Šϥʣ 10.1 ȁ̛͈Ȁěǎàƶ͢–γ*Ċі_̚Ǻ micropost.user ɟ˓ѕĬВǎà̛̫ȀžПžʶ ǻUþTn̛ it ě its ‚˜Ѝ it { should respond_to(:user) } its(:user) { should eq user } Tž Micropost ʬľ̫˜ЍΔćĴ гĊŠR̀ 10.5 ȁ͈ R̀ 10.5 ˜Ѝǎàě̛Ȁ*Җ̫–γ spec/models/micropost_spec.rb require 'spec_helper' describe Micropost do let(:user) { FactoryGirl.create(:user) } before { @micropost = user.microposts.build(content: "Lorem ipsum") } subject { @micropost } it { should respond_to(:content) } it { should respond_to(:user_id) } it { should respond_to(:user) } its(:user) { should eq user } it { should be_valid } describe "when user_id is not present" do before { @micropost.user_id = nil } it { should_not be_valid } end end 360 ͩ 10 ͥ ̛Ȁ̫ǎà Ĵ̛Ȁěǎà–γ–΀̫ User ʬľ ьǻU_Ĵ 10.1.4 ω‚ГΎ̫˜Ѝ̓ĴǻUüɮͮÞ̫˜ЍɮčþTĞ ư microposts ɟ˓ŠR̀ 10.6 ȁ͈ R̀ 10.6 ˜Ѝ̛ȀžПɮčþTĞư microposts ɟ˓ spec/models/user_spec.rb require 'spec_helper' describe User do before do @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") end subject { @user } . . . it { should respond_to(:admin) } it { should respond_to(:microposts) } . . . end ¢ş5ҷ̫˜Ѝų̛̓Ȁěǎà*Җ–γƊͮÞ5 üҲ¯ºÊ‘ҷїϡR̀R̀ 10.5 ěR̀ 10.6 ̫˜ЍƊþTѫѐ5 belongs_to :userŠR̀ 10.7 ȁ͈ě has_many :micropostsŠR̀ 10.8 ȁ ͈ R̀ 10.7 ǎà“Ɠ:belongs_to”̛Ȁ app/models/micropost.rb class Micropost < ActiveRecord::Base belongs_to :user validates :user_id, presence: true end R̀ 10.8 ̛Ȁ“ȞɽŐͳhas_many”ǎà app/models/user.rb class User < ActiveRecord::Base has_many :microposts . . . end 361 ̓ĴlưВΔćϥʣ 10.1ěR̀ 10.5R̀ 10.6͆wl̕ϵ5–γ̫Ńʄ̾Љ˸lіưВʨʙ ˜Ѝɮč þTѫѐ $ bundle exec rspec spec/models 10.1.4 ÅŔ Micropost às R̀ 10.6 ̫R̀ƫˎɽˤ‘˜Ѝѫѐ has_many ų̫̓–γIIʨ˜5ɮčþTĞư microposts ɟ˓ʄ ƄωǻU_$ Micropost ʬľÊ‘ȵƮɟ˓ěqƓ–΀і_˜Ѝ user.microposts ɟ˓̫ѕĬΔʔɮč$ɕ ΍ ǻUҲϬĴ User ʬľ̫˜Ѝ ̚Ǻ AǎàȁT̓ĴǻUϬµƶ ̚Ǻǎà̫ӀʐVĴȁµƶ̫ӀʐV ǻUϬȌ» ͑ɟ˓ȏǎàě̛Ȁ–γгʌƬѓ̫ɮĴ FactoryGirl ų̓–γɮNjŹɫ̫ŠR̀ 10.9 ȁ͈ R̀ 10.9 Űɗ̫ӀʐVɘVÓď5µƶǎà̫ɞӀʐV spec/factories.rb FactoryGirl.define do factory :user do sequence(:name) { |n| "Person #{n}" } sequence(:email) { |n| "person_#{n}@example.com"} password "foobar" password_confirmation "foobar" factory :admin do admin true end end factory :micropost do content "Lorem ipsum" user end end Ĵ FactoryGirl ǻUüҲϬĴµƶǎà̫ӀʐV Óď ̛ȀžПƊþTų̓ȁҲ̫–γ5 factory :micropost do content "Lorem ipsum" user end Ĵ ω _KΑǻUþTn̛ҷ̫ɟ˓̚Ǻ ͳǎà FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) 362 ͩ 10 ͥ ̛Ȁ̫ǎà Žĸ,öt әϻǧ¥n̛ user.microposts MɕȰƯ ЙớȀ̫ǎàιwЈǎà̫ʭƮcɮȧ˽àŴě Twitter ̫1ǭǻUơʀǎàȧ˽µƶɩҖzƮȵ²0Ɗɮɼɞµƶ̫ǎàĴɼÀҷϬ˜Ѝǎà̫ʭƮǻUϬµ ƶͳǎà FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago) ǻUȏͩ9ͳǎà̫µƶɩҖІ̫ɰ Aå 1.hour.ago¹̛5ɡ˕ 8.1 KΑ̫ƣÍ®ɕͩ ͳǎà̫ µƶɩҖϬɨ Aɮ 1.day.agoИ˕DZ n̛ FactoryGirl µƶǎàɮŐ(ɟt ǻUIþT̶ȷȦŲǎ àȁƓ̛̫ȀFactoryGirl _ѣѐ attr_accessible Ҥ¼іþTІŲѫƤǧ¥ιο̜ІŲ̫ created_at Ɠǝĭ$Ĵ Active Record ‚5Ҥ¼ŸʭЗɪ created_at ě updated_at Ɠǝ ɮ“Ӓ˓”²_ϧοÌІ$̷ư̫µƶɩҖǿěɹɞɩҖǿånȂÌȦŲ5~0_ϧϭ̱ œŐɕɕȰƯѢѺĩÓȠ SQLite ̫ѢѺĩЙó̫ǎàѹɮȧ˽ ID ʌȵƮ̫ĭʶR̀ 10.10 ̫˜ЍζŲ _ѫѐĴїʼ˜ЍR̀ ˎɽn̛ letή̛5 let!Йk“let bang”ĭ$ let ɟ˓ȦŲ̫õҀɮ“Ǯǝ” ̫üɽǃĊΛɽƼ̛ɩȃ_ϧµƶήǻUơʀїǎàõҀ͢åϧµƶїʠȃιwЈͳǎàɩҖǿ̫Ҽ Ʈɮʵ̫͆0wЈ5 @user.microposts ɕ΍ɮ̫͝ȁTǻUȃ̛5 let! ɟ˓ǁ¼̷ư̫õҀ͢åϧ µƶ R̀ 10.10 ˜Ѝ̛Ȁǎà̫ʭƮ spec/models/user_spec.rb require 'spec_helper' describe User do . . . describe "micropost associations" do before { @user.save } let!(:older_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) end let!(:newer_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago) end it "should have the right microposts in the right order" do expect(@user.microposts.to_a).to eq [newer_micropost, older_micropost] end end end 363 ї˜Ѝ ɼ–Ҏ̫ ϡɮ expect(@user.microposts.to_a).to eq [newer_micropost, older_micropost] їϡR̀ϥɪȁµƶ̫ǎàưВȧ˽µƶɩҖzƮȵ²åɼɞµƶ̫ǎàȵĴɼÀҷї˜Ѝ˕Ųɮɣ˓ѫѐ ̫ĭ$ǎàәϻɮȧ˽ ID ȵƮ̫å [older_micropost, newer_micropost]ї˜ЍĈɩ0ӎЈ5 has_many –γɼŃʄ̫ɐʔɮčʵ͆åʨ˜ user.microposts ѕĬ̫Δʔɮčɮɕ΍˜ ̛»̫ to_a ɟ ˓Ĵ 4.3.1 ω KΑѐ_ȏ @user.microposts M¶ţ̉ǙActive Record ̫“үćR̕collection proxy”тȮǺ ɕ΍TtěǻUȂÌΠ¢̫ɕ΍ˀч ϬϽї˜ЍѫѐǻUϬn̛ Rails ̫ default_scope ɟ˓іϬІŲŮ̫ :order ìɕŠR̀ 10.11 ȁ ͈їɮǻUͩ ʭȷ϶k̛Ł̫ʫǖĴͩ 11 ͥ _KΑk̛Łɹ υ̛̫˓ R̀ 10.11 ѫѐ default_scope ІŲǎà̫ȵƮ app/models/micropost.rb class Micropost < ActiveRecord::Base belongs_to :user default_scope -> { order('created_at DESC') } validates :user_id, presence: true end ǻUѫѐ microposts.created_at DESC ІŲ5ȁҲ̫ȵƮ˜ DESC Ĵ SQL ɮ“zƮ”̫DZǜåȧ˽̜ ɞ»ɧї͑ҼƮȵƮ M Rails 4.0 Ʒţȁɽ̫k̛ŁѹҲϬѫѐØĉ®ɕ̫ɟƻŲ)®ɕ̫ѕĬ~$ȁҲ̫ʋVї(‚%Ϭ̫şŌ ɮk̛Ł̫ʋV̛͢åϹͯüĴҲϬɩȃȆϡȁTý‚“ǮǝϹͯ”ʄoȁ̛̫Øĉ®ɕɮ -> { order('created_at DESC') } ї͑žПý Proc Ǽ lambdaT -> ƷŘĊҷк̽ R̀ĻЛ̛ call ɟ˓ɩȃȆϡĻ ̫R̀ǻUþTĴ ȸ¼ÿ ̺  >> -> { puts "foo" } => # >> -> { puts "foo" }.call foo => nil Proc Ɠ: Ruby ДϷ̫ӑΈÉιȁTŠʔˎɽ͢¾̕ϵ0̛ȘǏ /:đdestroy Ҧ5ІŲǡǃ̫ȵƮŏǻUіϬžǎàʬľ‚û һɌјǻUĴ 9.4 ω KΑѐͰ̕ĕɮɽʈҤ·Ҧ̛Ȁ ̫Ѷ(Ĵ·Ҧ̛Ȁ̫ĈɩƊɽǐϬȏВ̛Ȁòƞ̫ǎà0·ҦžʶǻUþTΠ¢ ˜Ѝʨ˜ǃ̛Ȁϧ ·ҦĊ˜òƞ̫ǎàɮčіĴɕȰƯ  364 ͩ 10 ͥ ̛Ȁ̫ǎà $5ιŒʵ̫͆˜Ѝǎàɮčϧ·Ҧ5ǻUϬơ̑Ȁ̫ ͳǎàЭ~Ζ ƎѸõҀ˼ĊŸ·Ҧї̛Ȁ žʶ ͑ˀч̶ϯ̫ų̓ɟƻŠȁ͈ microposts = @user.microposts.to_a @user.destroy expect(microposts).not_to be_empty microposts.each do |micropost| # Make sure the micropost doesn't appear in the database. end ǻUЛ̛5 to_a ɟ˓ӑɐĵŎ¼5 YǎϘ²ϥǻUіÊ‘5ҷїϡ expect(microposts).not_to be_empty їɮ YðwҧѵƄǏ˱ȳ5 to_aŠʔˎɽ to_a ̫Џ ɦ·Ҧ5̛ȀƊ_·ȳ microposts õҀ ̫В̛Ȁ̫ǎàѶ( microposts.each do |micropost| # Make sure the micropost doesn't appear in the database. end ƊH(0˜Ѝ5ĭ$ microposts ɮ̫͝ ǻUþTѫѐҷ̫R̀͆ϻǎàĴɕȰƯ microposts.each do |micropost| expect(Micropost.where(id: micropost.id)).to be_empty end їѾǻƯ̫ɮ Micropost.where9ˎ̛ Micropost.findĭ$ŠʔˎɽʙБ»ЁDŽ where _ѕĬ ͝ ~žПή find _Ȓ¬ƸƤ˜Ѝ͝~žПϬɹŹɫŠʔlşŚǯ̾ѱŠh˜ЍƸƤþTn̛ҷ̫R̀ expect do Micropost.find(micropost) end.to raise_error(ActiveRecord::RecordNotFound) Űɗ̫˜ЍR̀ŠR̀ 10.12 ȁ͈ R̀ 10.12 ˜Ѝ̛Ȁ·ҦĊȁòƞ̫ǎàɮč0ϧ·Ҧ5 spec/models/user_spec.rb require 'spec_helper' describe User do . . 365 . describe "micropost associations" do before { @user.save } let!(:older_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) end let!(:newer_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago) end . . . it "should destroy associated microposts" do microposts = @user.microposts.to_a @user.destroy expect(microposts).not_to be_empty microposts.each do |micropost| expect(Micropost.where(id: micropost.id)).to be_empty end end end end ϬϽR̀ 10.12 ̫˜ЍѫѐǻU̙πҲϬʑ ϡŰɗ̫R̀üҲĴ has_many ɟ˓ ІŲ ìɕå þŠR̀ 10.13 ȁ͈ R̀ 10.13 wЈ̛Ȁ̫ǎàĴ·Ҧ̛Ȁ̫Ĉɩ0_ϧ·Ҧ app/models/user.rb class User < ActiveRecord::Base has_many :microposts, dependent: :destroy . . . end ҷR̀ ɽї( ϡ has_many :microposts, dependent: :destroy ˜ ̫ dependent: :destroy ІŲ͘ƮĴ̛Ȁϧ·Ҧ̫ɩ|˜ȁƓ̫ǎà0Ϭϧ·Ҧї( ʌŠʔͰ̕ ĕ·Ҧ5̛ȀɕȰƯ Ɗ_¬̓ɣ%̫ǎà5 πʶ̛Ȁěǎà*Җ̫–γƊІΦş5ȁɽ̫˜ЍưВѹþTѫѐ5 366 ͩ 10 ͥ ̛Ȁ̫ǎà $ bundle exec rspec spec/ 10.1.5 źľ¦S=ˆ ĴΔʉϼЅ Micropost ʬľ*ÀǻUіϬ$ǎà̫ŹÊɕȰӎЈì˽ 2.3.2 ωě user_id ʠ content Ɠǝι$͝ήіϬҤ¼Ź̫ґƴιŐ: 140 Ūͨїȃɮ̻ʵ̫“ǎ”àǻUϬΠ¢̫˜Ѝ ě 6.2 ω ž̛Ȁʬľ̫ӎЈ˜ЍͶbŠR̀ 10.14 ȁ͈ R̀ 10.14 ˜Ѝ Micropost ʬľ̫ɕȰӎЈ spec/models/micropost_spec.rb require 'spec_helper' describe Micropost do let(:user) { FactoryGirl.create(:user) } before { @micropost = user.microposts.build(content: "Lorem ipsum") } . . . describe "when user_id is not present" do before { @micropost.user_id = nil } it { should_not be_valid } end describe "with blank content" do before { @micropost.content = " " } it { should_not be_valid } end describe "with content that is too long" do before { @micropost.content = "a" * 141 } it { should_not be_valid } end end ě 6.2 ω ʠĴR̀ 10.14 ǻƯ»5Ūͨ".͕ʌ˜ЍǎàŹґƴ̫ӎЈ $ rails console >> "a" * 10 => "aaaaaaaaaa" >> "a" * 141 => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 367 ǻUҲϬĴ͘Ʈ ʑҷїϡR̀ validates :content, presence: true, length: { maximum: 140 } Micropost ʬľ̫ɼΐR̀ŠR̀ 10.15 ȁ͈ R̀ 10.15 Micropost ʬľ̫ɕȰӎЈ app/models/micropost.rb class Micropost < ActiveRecord::Base belongs_to :user default_scope -> { order('created_at DESC') } validates :content, presence: true, length: { maximum: 140 } validates :user_id, presence: true end 10.2 Ðā¦S ƌͰǻUіˎų̶̓ȷĴΤҹ òƞǎà̫ÉιƃĴ 10.3.2 ωų̓ѐǻUіɮɽÈ˓ɯ͈ǎàƫžɯ͈ ̫Źјϡ˜ЍǻUƃȧ˽ Twitter ̫ɟƻ̛Ȁ̫ǎàĴ index ҹҷ ɯ͈ήĴ show ҹҷ ʐǜijŠ ij 10.4 ȁ͈ǻU_µƶ ANjͮÞ̫ ERb R̀Ĵ̛Ȁ̫Ьəҹҷɯ͈ǎà˼ĊϬĴ 9.3.2 ω ų̫̓ɕȰ ̚Ǻĩ ʑ̚Ǻǎà̫R̀їʠǻUȃɽŹþTɯ͈ ě 8.2.1 ω ž̨DŽʆ¼̫KΑͶb10.2.1 ω0_ΒƤƃ A‹΁ȹѡ»ńʝѾ˼ĊŸ  ̫Mʝƍó¬ ʌŠʔ̕ϵгʌɽ˸įҭŐ˸ίǏl̫Q¬_Ĵ 10.2.2 ωnj»ĬȔ 10.2.1 6‡ö®ʼnÊŲű ǻUĴ̛Ȁ̫ request spec ʑžɯ͈ǎà̫˜ЍǻUѼ̛̫ɟ˓ɮѫѐӀʐVµƶ©ͳǎà˼Ċʨʙ ̛ȀЬəҹҷɮčɯ͈5ї©ͳǎàĈɩǻUіϬӎЈɮčɯ͈5Šij 10.4 ȁ͈̫ǟ̫ǎàɕҀ ǻUþTn̛ let ɟ˓µƶǎàѐŠR̀ 10.10 ȁ͈ǻUơʀ̛Ȁěǎà̫–γ͢å̚ɐїʠǎàȃιɯ ͈Ĵ̛Ȁ̫Ьəҹҷ ȁTǻUϬn̛ let! ɟ˓ let(:user) { FactoryGirl.create(:user) } let!(:m1) { FactoryGirl.create(:micropost, user: user, content: "Foo") } let!(:m2) { FactoryGirl.create(:micropost, user: user, content: "Bar") } before { visit user_path(user) } 368 ͩ 10 ͥ ̛Ȁ̫ǎà ij 10.4 ɯ͈5ǎà̫Ьəҹҷʐǜij ȧ˽ҷї͑ɟƻŲ)5ǎàĊǻUƊþTn̛R̀ 10.16 ̫R̀˜Ѝ̛ȀЬəҹҷ ɮčɯ͈5їAǎà R̀ 10.16 ʨ˜̛ȀЬəҹҷɮčɯ͈5ǎà̫˜Ѝ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . . . describe "profile page" do let(:user) { FactoryGirl.create(:user) } let!(:m1) { FactoryGirl.create(:micropost, user: user, content: "Foo") } let!(:m2) { FactoryGirl.create(:micropost, user: user, content: "Bar") } before { visit user_path(user) } it { should have_content(user.name) } 369 it { should have_title(user.name) } describe "microposts" do it { should have_content(m1.content) } it { should have_content(m2.content) } it { should have_content(user.microposts.count) } end end . . . end ˕DZǻUþTĴ–γ–΀̫ɟ˓Л̛ count ɟ˓ user.microposts.count ї count ɟ˓ɮNjδɪ̫þT̶ȷĴɕȰƯƏΙϹɕҀ0ƊɮЗcount ̫Ϲɕѐ͘ɮȏǎàMɕȰƯ ó¬ʌ˼ĊŸĴȁnj̫ɕ΍Л̛ length ɟ˓Šʔїʠ‚̫ЏǎàɕҀ ɦNjŐ̫Џɐ̐Ɗ_Nje ˜ųcount ɟ˓_̶ȷĴɕȰƯƏ ΙϹ̛Ȁ̫ǎàɕҀŠʔΙϹɕҀL˼ɮ͘Ʈ̫ǝι̘ӂ̫ЏlþTn ̛“ϹɕΟū”ј ʷȼѬ ĴʑR̀ 10.18 *ÀR̀ 10.16 ̫˜Ѝɮɣ˓ѫѐ̫ѐ̓ĴǻUþTĴ̛Ȁ̫Ьəҹҷ ʑ Aǎ àŠR̀ 10.17 ȁ͈ R̀ 10.17 Ĵ̛ȀЬəҹҷ ʑǎà app/views/users/show.html.erb <% provide(:title, @user.name) %>
    . . .
    <% if @user.microposts.any? %>

    Microposts (<%= @user.microposts.count %>)

      <%= render @microposts %>
    <%= will_paginate @microposts %> <% end %> 370 ͩ 10 ͥ ̛Ȁ̫ǎà
    ǎà²ϥ͙Ċ¯ʑ̓Ĵ̺̺˜PѸ¯ĴїʼR̀ if @user.microposts.any?ĴR̀ 7.24 Ϯѐ Ͷb̛̫˓̫k̛ɮŠʔ̛Ȁˎɽòƞǎà̫ЏƊ_ɯ͈Ċҷ̫²ϥ іϬ˕DZ ĴR̀ 10.17 ǻU0ʑ5ǎà̫¯ҹɯ͈Éι <%= will_paginate @microposts %> Šʔě̛Ȁ΂Ƽҹҷ žư̫R̀ìϮR̀ 9.34ˀч̫Џ_ò̓*Àȁ̛̫R̀ɮ <%= will_paginate %> *À*ȁTþT̶ȷЛ̛ɮĭ$Ĵ Users ȸ¼ĩ will_paginate әϻ͘Ʈ ūĴ ĉ$ @users ̫õҀ Ĵ 9.3.3 ω KΑѐВõҀ̫~ǐҽɮ AvtiveRecord::Relation ̫ųo̓Ĵϝ˼ǻUіĴ Users ȸ ¼ĩ cɮǻUϬžǎà¯ҹȁT will_paginate ɟ˓ϬȦŲ @microposts õҀk$ìɕǃ˼5ǻU іϬĴ show Ìk Ų) @microposts õҀìϮR̀ 10.19 ȷ̽іɯ͈5ǃÀǎà̫ɕҀ

    Microposts (<%= @user.microposts.count %>)

    ÀҷKΑѐ@user.microposts.count ̫k̛ě User.count ͶbѐΙϹ̫ǎàɕҀæɮƶ͢Ĵ̛Ȁě ǎà̫–γ–΀̫ ɼĊǻUʌ̺ ɯ͈ǎà̫²ϥ
      <%= render @microposts %>
    їʼR̀n̛5 ɽƮ²ϥʜͭ olɯ͈ ǎà²ϥѐ–Ҏ̫Ѹ¯ɮѫѐ ǎàƎѸϱijų̫̓Ĵ 9.3.4 ω KΑѐŠ̫R̀ <%= render @users %> _n̛ĉ$ _user.html.erb ̫ƎѸϱij˪ʘ @users õҀ ̫ʿ ̛ȀĭʶŠ̫R̀ <%= render @microposts %> _žǎà‚Ĉʠ̫˪ʘɈkȁTǻUϬµƶĉ$ _micropost.html.erb ̫ƎѸϱijūɎĴǎàžư̫ϱ ijɘVř ŠR̀ 10.18 ȁ͈ R̀ 10.18 ɯ͈Þͳǎà̫ƎѸϱij app/views/microposts/_micropost.html.erb 371
  • <%= micropost.content %> Posted <%= time_ago_in_words(micropost.created_at) %> ago.
  • їʼR̀n̛5 time_ago_in_words ƣÍɟ˓_Ĵ 10.2.2 ω KΑ ij 10.5 ˦Ê5ɯ͈ǎàR̀Ċ̛̫ȀЬəҹҷѐіˎɽǎàþɯ͈ πʶƌͰŲ)5ȁҲ̫’ѸϱijcɮR̀ 10.16 ̫˜ЍLɧɣ˓ѫѐȼ͈ʂŲ) @microposts õҀÊ ‘R̀ 10.19 ̫R̀Ċ˜ЍƊþTѫѐ5 R̀ 10.19 Ĵ Users ȸ¼ĩ̫ show Ìk ʑ @microposts ųoõҀ app/controllers/users_controller.rb class UsersController < ApplicationController . . . def show @user = User.find(params[:id]) @microposts = @user.microposts.paginate(page: params[:page]) 372 ͩ 10 ͥ ̛Ȁ̫ǎà end . . . end И˕DZ  paginate ɟ˓ɮŐ(̫ɴιŮ̙πþTѫѐ–γ–΀Ĵ microposts ɕȰϥ ó¬ʿ¯ҹ Ϭɯ͈̫ǎà ̓ĴǻUþTʙ̺ ´Πş̛̫ȀЬəҹҷ5Šij 10.5 ȁ͈þι_¬+l̫DZəї0ɮ̕ȁǃ˼̫ĭ $ǻUіˎɽòƞǎàĖҷǻUƊʌòƞǎà 10.2.2 ā.¦S Ĵ 10.2.1 ω $5ɯ͈ǎàµƶ5©ϱijcɮΔʔɽ˸ΖÇ$5ɌõїǦÂǻUϬĴ 9.3.2 ω ̛ »̫͈oɕȰ̚Ǻĩ ʑ̚ǺǎàɕȰ̫R̀ŠʔΖȁɽ̛̫Ȁѹ̚Ǻ Aǎà̫ЏϬ̛Njґ̫ɩҖȁTǻ UɵüΖÀ”̛Ȁ3̚ǺǎàɕȰїϬ̛» User.all ɟ˓̫ :limit ѥһ 4 users = User.all(limit: 6) ǻUϬ$ʿ̛Ȁ̚Ǻ 50 ͳǎàїɕҀœ:Þҹɯ͈̫ 30 ͳҤ¼n̛ Faker gem ͮt̫ Lorem.sentence ɟ˓̚Ǻʿͳǎà̫ŹFaker::Lorem.sentence ̚Ǻ̫ɮ lorem ipsum ͈oɘŪǻ UĴͩ 6 ͥ KΑѐlorem ipsum ηĊɽ ʼɽж̫ɏ8R̀ 10.20 ɯ͈̫ɮyɌĊ̫͈oɕȰ̚Ǻĩ R̀ 10.20 Ĵ͈oɕȰ̚Ǻĩ ʑ̚Ǻǎà̫R̀ lib/tasks/sample_data.rake namespace :db do desc "Fill database with sample data" task populate: :environment do . . . users = User.all(limit: 6) 50.times do content = Faker::Lorem.sentence(5) users.each { |user| user.microposts.create!(content: content) } end end end ǃ˼ŠʔϬ̚Ǻ͈oɕȰǻUϬȆϡ db:populate ĚS 3. oŠοŲ)5؈̫ 5 ̛Ȁě n̛ Gravatar әϻ؈̫ 1 ̛Ȁ 4. Šʔlžїɟ˓̚Ǻ̫ SQL dz—жþTʙ̺ log/development.log ɘV 373 $ bundle exec rake db:reset $ bundle exec rake db:populate $ bundle exec rake test:prepare ˼ĊǻUƊι̺» 10.2.1 ω ÐÌ̫ʔų5Ĵ̛ȀЬəҹҷɯ͈5̚Ǻ̫ǎà5¶ʷΔʔŠij 10.6 ȁ͈ ij 10.6 ̛ȀЬəҹҷ/users/1 ɯ͈̫ƈʂʠƻÔ̫ǎà²ϥ ij 10.6 ɯ͈̫ǎà²ϥіˎɽʑʠƻѶǻUƊʑ AʠƻìϮR̀ 10.216Ÿ̺ ҹҷɯ͈̫ɐ ʔij 10.7 ɯ͈̫ɮͩ ̛ȀǃĄ̀DŽ̛Ȁ̫Ьəҹҷij 10.8 ɯ͈̫ɮû ̛Ȁ̫Ьəҹҷij 10.9 ɯ͈̫ɮͩ ̛ȀЬəҹҷ̫ͩ 2 ҹҹҷƱѸіɯ͈5¯ҹ҈ȷ˕DZϯżїƦijǻUþT̺»ǎàĊҷ ɯ͈5й͎òƞ̫ɩҖoŠ“Posted 1 minute ago.”їɐʔɮѫѐR̀ 10.18 ̫ time_ago_in_words ɟ˓ų̫̓ѐ _Ÿ½ɞҹҷl_ò̓їAɘŪqȰǃÀɩҖοÌɹɞ5 5. Faker ̫ lorem ipsum ɘʄɮϧІϹ$ҩʆ̚Ǻ̫ȁTl̫͈oǎàþιěǻ̫ ʠ 6. $5ϡɘɟtR̀ 10.21 ųҠÓď5ʄ̛ͥ»̫ȁɽ CSS 374 ͩ 10 ͥ ̛Ȁ̫ǎà ij 10.7 ɯ͈5ǎà̛̫ȀЬəҹҷ/users/1 R̀ 10.21 ǎà²ϥ̫ʠƻÓď5ʄ̛ͥ»̫ȁɽʠƻ app/assets/stylesheets/custom.css.scss . . . /* microposts */ .microposts { list-style: none; margin: 10px 0 0 0; li { padding: 10px 0; border-top: 1px solid #e8e8e8; } } .content { display: block; } 375 .timestamp { color: $grayLight; } .gravatar { float: left; margin-right: 10px; } aside { textarea { height: 100px; margin-bottom: 5px; } } ij 10.8 û ̛Ȁ̫Ьəҹҷ0ɯ͈5ǎà²ϥ/users/5 376 ͩ 10 ͥ ̛Ȁ̫ǎà ij 10.9 ǎà¯ҹ҈ȷ/users/1?page=2 10.3 ¦Sþ:ûÂ, ǎà̫ɕȰʬľʐƶş50Π¢5̷–̫ϱijɘVȷʌǻU̫Ʒòѿ˸ɮѫѐΤҹòƞǎàĴų̫̓ѐ ͘ ǻU_ͩʭ̛»ϥÞʌµƶЬˬї ʭµƶ̫ɮ Microposts Ьˬ7ʄωǻUі_¶ʷų̓ÌǙ²ϥ status feedĴͩ 11 ͥŸŰĦɼĊě Users ЬˬͶbǻUіϬų̓ĴΤҹ ·Ҧǎà̫Éι ѝÉι̫ų̓ě*À̫ǭoɽ ˸ɮ ʠ̫ĵɟҲϬ̆º˕DZѶƊɮMicroposts Ьˬ̷–̫ҹҷɮѫ ѐ Microposts ȸ¼ĩų̫̓ήɮqЯ: Users ě StaticPages ȸ¼ĩї0ƊDZĘ̽Microposts Ьˬ̫м̜ІΦ ɮNjͮÞ̫ŠR̀ 10.22 ȁ͈R̀ 10.22 ̫R̀ȁRϥ̫ͨć REST Δʐ̫м̜Šϥʣ 10.2 ȁ͈ϥ ̫м ̜üɮϥʣ 2.3 ̫ Ѹ¯ѐм̜ϝ˼ͮÔ5cӀ͈̽ų̫̓ѐ͘ҲϬɹӑΈ̫Ȏʅή_§ƄR̫̀Ŏ ʇƴMͩ 2 ͥгǻUƊÙ¯qЯμȂʖѐ̓ĴǻUƃςƹμȂʖ̫œѸ¯Éι R̀ 10.22 Microposts Ьˬ̫м̜ІΦ config/routes.rb SampleApp::Application.routes.draw do resources :users resources :sessions, only: [:new, :create, :destroy] resources :microposts, only: [:create, :destroy] 7. ûŏЬˬ¯ºɮ 7.2 ω ̫ Users Ьˬě 8.1 ω ̫ Sessions Ьˬ 377 . . . end ϥʣ 10.2 R̀ 10.25 ІΦ̫ Microposts Ьˬм̜ HTTP Иˇ URL Ìk k̛ POST /microposts create µƶɞǎà DELETE /microposts/1 destroy ·Ҧ id $ 1 ̫ǎà 10.3.1 ĽũūI Ʒò Microposts Ьˬ̫ͩ ʷǻUϬĴ Microposts ȸ¼ĩ ų̓ЇҕҤ¼ǻUϬų̫̓ɐʔNjͮÞ ϋϬЇҕ create ě destroy ÌkƊϬ̨DŽ҂žЇҕҤ¼̫ RSpec ˜ЍŠR̀ 10.23 ȁ͈Ĵ 10.3.4 ω ǻUі_ ˜ЍƫʑͩƏwȓȺɠ͆wüɽǎà̫òƞέȃι·ҦВǎà R̀ 10.23 Ҥ¼Їҕ Microposts Ьˬ̫˜Ѝ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do describe "for non-signed-in users" do let(:user) { FactoryGirl.create(:user) } . . . describe "in the Microposts controller" do describe "submitting to the create action" do before { post microposts_path } specify { expect(response).to redirect_to(signin_path) } end describe "submitting to the destroy action" do before { delete micropost_path(FactoryGirl.create(:micropost)) } specify { expect(response).to redirect_to(signin_path) } end 378 ͩ 10 ͥ ̛Ȁ̫ǎà end . . . end end end ѝR̀ˎɽn̛åƃų̫̓Τҹ̠ҷήɮ̶ȷĴ Microposts ȸ¼ĩƏҷɈk Šʔċ /microposts òѡ POST И ˇPOST microposts_path Їҕ̫ɮ create ÌkǼέċ /microposts/1 òѡ DELETE Иˇdelete micropost_path(micropost) Їҕ̫ɮ destroy Ìk³_тċ̨DŽҹҷ——ǻUĴR̀ 9.14 Ɗ̛ѐї ͑ɟ˓ ǻUϬž͘Ʈ̫R̀‚˸ѿʐ˼ĊŸÊ‘͘Ʈ ϽR̀ 10.23 ̫˜ЍѫѐĴ 9.2.1 ω ǻUŲ)5  ĉ$ signed_in_user ̫8Àѐ˰ĩìϮR̀ 9.12͆wЇҕ̷–̫Ìk*À̛ȀϬ̨DŽѶɩǻUü ҲϬĴ Users ȸ¼ĩ n̛ї8Àѐ˰ĩcɮ̓ĴǻUĴ Microposts ȸ¼ĩ 0Ϭ̛»Ѷ(ǻUƊȏŮ͗» Sessions ̫ƣÍɟ˓ ŠR̀ 10.24 ȁ͈8 R̀ 10.24 ȏ signed_in_user ɟ˓͗» Sessions ƣÍɟ˓ app/helpers/sessions_helper.rb module SessionsHelper . . . def current_user?(user) user == current_user end def signed_in_user unless signed_in? store_location redirect_to signin_url, notice: "Please sign in." end end . . . end $5ѵR̀ѿŎĈɩіϬȏ signed_in_user M Users ȸ¼ĩ ·ȳ 8. ǻUĴ 8.2.1 ω KΑѐәϻǧ¥ƣÍɟ˓üιĴϱij n̛ĭʶϬĴȸ¼ĩ n̛ Sessions ƣÍɟ˓ƊϬĴ Application ȸ¼ĩ ʑR̀ include SessionHelper 379 ʑ5R̀ 10.24 *ĊǻUƊþTĴ Microposts ȸ¼ĩ n̛ signed_in_user ɟ˓5ĭʶǻUƊþTn̛ R̀ 10.25 ̫8Àѐ˰ĩʌҤ¼Їҕ create ě destroy Ìk5ĭ$ǻUˎɽn̛ĚSϡ̚Ǻ Microposts ȸ¼ĩɘVĭʶҲϬȂ̵ƶ R̀ 10.25 Ĵ Microposts ȸ¼ĩ ʑЇҕҤ¼Éι app/controllers/microposts_controller.rb class MicropostsController < ApplicationController before_action :signed_in_user def create end def destroy end end ˕DZǻUˎɽɪ͆ȦŲ8Àѐ˰ĩϬҤ¼̫ÌkɽĠ©ĭ$әϻǧ¥Iɽ̫Ìkѹ_ϧҤ¼Šʔǻ UϬʑͩÌkoŠ index Ìkʂ̨DŽ̛̫ȀþTЇҕѶ(ǻUƊϬɪ̫͆ȦŲϬҤ¼̫Ìk5 class MicropostsController < ApplicationController before_action :signed_in_user, only: [:create, :destroy] def index end def create end def destroy end end ̓Ĵ˜ЍưВþTѫѐ5 $ bundle exec rspec spec/requests/authentication_pages_spec.rb 10.3.2 Ež¦S Ĵͩ 7 ͥ ǻUų̓5̛Ȁ˕žÉιɟ˓ɮn̛ HTML ϥÞċ Users ȸ¼ĩ̫ create Ìkòѡ POST Иˇ µƶǎà̫Éιų̓гʌɮͶb̫ɼœ̫Ĉ˸Ĵ:ϥÞɮɎĴÞ̫̌ҹҷ /microposts/new ήɮĴΤͤ ̫ӊҹʬZ TwitterĴʢĵĸ /ʐǜijŠij 10.10 ȁ͈  ʭȷ϶ӊҹɩɮij 5.6 ѶʠũĴҹҷ Ѹɽ“Sign up now!”҈ȷȧ҄ĭ$µƶǎà̫ϥÞüž̨DŽĊ ̛̫Ȁɽ̛ȁTʄω̴̫ʜ* ƊɮʢƠ̇̄Ą̫̏DŽ̉Ǚɯ͈Ĉ̫ӊҹŹŠR̀ 10.28 ȁ͈ѐĴʶ* ÀǻUþTΠ¢˜Ѝě̛ȀЬˬ ʠǻUϬn̛үǺ˜Ѝ 380 $ rails generate integration_test micropost_page ͩ 10 ͥ ̛Ȁ̫ǎà ij 10.10 ÓďµƶǎàϥÞ̫ӊҹʐǜij žµƶǎàÉι̫˜Ѝěžµƶ̛ȀÉι̫˜ЍìϮR̀ 7.16ͶbŠR̀ 10.26 ȁ͈ R̀ 10.26 žµƶǎàÉι̫˜Ѝ spec/requests/micropost_pages_spec.rb require 'spec_helper' describe "Micropost pages" do subject { page } let(:user) { FactoryGirl.create(:user) } before { sign_in user } describe "micropost creation" do before { visit root_path } 381 describe "with invalid information" do it "should not create a micropost" do expect { click_button "Post" }.not_to change(Micropost, :count) end describe "error messages" do before { click_button "Post" } it { should have_content('error') } end end describe "with valid information" do before { fill_in 'micropost_content', with: "Lorem ipsum" } it "should create a micropost" do expect { click_button "Post" }.to change(Micropost, :count).by(1) end end end end ҷǻUʌΠ¢ Microposts ȸ¼ĩ create Ìk̫R̀ě Users ȸ¼ĩ̫ɽ˸ͶbìϮR̀ 7.26%Ϭ̫× ºɮµƶǎàɩϬn̛̛Ȁěǎà̫–γ–΀ʌʐƶǎàžПŠR̀ 10.27 ȁ͈ R̀ 10.27 Microposts ȸ¼ĩ̫ create Ìk app/controllers/microposts_controller.rb class MicropostsController < ApplicationController before_action :signed_in_user def create @micropost = current_user.microposts.build(micropost_params) if @micropost.save flash[:success] = "Micropost created!" redirect_to root_url else render 'static_pages/home' end end def destroy end private 382 ͩ 10 ͥ ̛Ȁ̫ǎà def micropost_params params.require(:micropost).permit(:content) end end ǻUn̛R̀ 10.28 ʌʐƶµƶǎàȁҲ̫ϥÞїϱij_ʢƠ̇̄Ą̫̏DŽ̉Ǚɯ͈Ĉ̫ HTML Ź R̀ 10.28 Ĵӊҹ ʑµƶǎàȁҲ̫ϥÞ app/views/static_pages/home.html.erb <% if signed_in? %>
    <% else %>

    Welcome to the Sample App

    This is the home page for the Ruby on Rails Tutorial sample application.

    <%= link_to "Sign up now!", signup_path, class: "btn btn-large btn-primary" %>
    <%= link_to image_tag("rails.png", alt: "Rails"), 'http://rubyonrails.org/' %> <% end %> ѝR̀ if-else ʋVДú̫Ć¯ɊÓď̫R̀ŕŐɽ˸4ĴΌ1 10.5 ωǻU_јϡ^Ôȏ¯Ɋ ̫R̀Ɏ‘ƎѸϱij ѐR̀ 10.28 ̛»̫ƎѸϱij_̢kΌ1̓ĴƊʌµƶ ̛ȀxǠrьʞƎѸ ϱijŠR̀ 10.29 ȁ͈µƶǎà̫ϥÞƎѸϱijŠR̀ 10.30 ȁ͈ R̀ 10.29 ̛ȀxǠrьʞƎѸϱij app/views/shared/_user_info.html.erb 383 <%= gravatar_for current_user, size: 52 %>

    <%= current_user.name %>

    <%= link_to "view my profile", current_user %> <%= pluralize(current_user.microposts.count, "micropost") %> ěR̀ 9.25 ʠR̀ 10.29 n̛5R̀ 7.30 Ų)̫ gravatar_for ƣÍɟ˓ ˕DZě̛ȀЬəҹҷ̫rьʞͶbìϮR̀ 10.20R̀ 10.29 ̛̫ȀxǠ0ɯ͈5̛Ȁòƞ̫ǎàɕҀ ѐɯ͈ɽΎǎ̫ƛºĴ̛ȀЬəҹҷ̫rьʞ “Microposts” ɮk$ʜͭn̛̫ȁT“Microposts (1)”їʠ ̛̫˓ɮć̫̕ήĴʄo ŠʔЗ“1 microposts”̫ЏƊɽ˸ćД˓5ȁTǻUЛ̛5 pluralize ɟ˓ ɯ͈Ǻ“1 micropost”“2 microposts”ͪ ҷǻUʌΠ¢µƶǎàϥÞ̫ƎѸϱijŠR̀ 10.30 ȁ͈ěR̀ 7.17 ̫˕žϥÞɮͶb̫ R̀ 10.30 µƶǎàϥÞƎѸϱij app/views/shared/_micropost_form.html.erb <%= form_for(@micropost) do |f| %> <%= render 'shared/error_messages', object: f.object %>
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>
    <%= f.submit "Post", class: "btn btn-large btn-primary" %> <% end %> ŠʔϬR̀ 10.30 ̫ϥÞþ̛ǻUіϬ‚V8ͩ ě*À ʠǻUϬѫѐ–γ–΀Ų) @micropost õҀ @micropost = current_user.microposts.build ¢‘ȸ¼ĩĊŠR̀ 10.31 ȁ͈ R̀ 10.31 Ĵ home Ìk Ų) @micropost ųoõҀ app/controllers/static_pages_controller.rb class StaticPagesController < ApplicationController def home @micropost = current_user.microposts.build if signed_in? end 384 ͩ 10 ͥ ̛Ȁ̫ǎà . . . end R̀ 10.31 ̫R̀ɽ şŌŠʔǻUǓЁÊ‘Ϭˇ̛Ą̏DŽ̫Ҥ¼̷ư̫˜Ѝ_ŗХ ǻUϬ‚̫ͩ9V8ɮѿ¢ҌЕȼ͈xǠƎѸϱijϽ <%= render 'shared/error_messages', object: f.object %> їϡR̀ιʵ͆ѓϡlþιіЁnjĴR̀ 7.23 ҌЕȼ͈xǠ̫ƎѸϱijR̶̀ ȷƼ̛5 @user õҀc̓ĴǻUȼp̫õҀæɮ @micropostĭʶǻUϬΠ¢ ɞ̫ҌЕȼ͈xǠƎѸ ϱijͰ`‘̫ɮH(õҀѹιʵƤn̛ƬşϥÞ̫ĻõҀ f þTѫѐ f.object ϓóǃÀ̫žПĭ ʶĴ form_for(@user) do |f| f.object ̫ѕĬ~ɮ @user Ĵ form_for(@micropost) do |f| f.object ̫ѕĬ~ɮ @micropost ǻUϬѫѐ  Hash ȏžП`‘ƎѸϱij˜~ɮВžПҎɮƎѸϱij ȁҲ̫õҀĉ͖Šҷ̫R̀ȁ ͈ <%= render 'shared/error_messages', object: f.object %> ȮúЏЗobject: f.object _µƶ ĉ$ object ̫õҀp error_messages ƎѸϱijn̛¹̛ї žПǻUƊþTΠ¢Ĉ̫ҌЕȼ͈xǠŠR̀ 10.32 ȁ͈ R̀ 10.32 yɌR̀ 7.23 ̫ҌЕȼ͈xǠƎѸϱijŠʔ`‘˜PžП0þTn̛ app/views/shared/_error_messages.html.erb <% if object.errors.any? %>
    The form contains <%= pluralize(object.errors.count, "error") %>.
      <% object.errors.full_messages.each do |msg| %>
    • * <%= msg %>
    • <% end %>
    <% end %> ̓ĴR̀ 10.26 ̫˜ЍưВþTѫѐ5 $ bundle exec rspec spec/requests/micropost_pages_spec.rb ѐUsers Ьˬ̷–ϱij̫ request spec ˜ЍæŗХ5ĭ$˕žěΠщ̛Ȁ̫ϥÞn̛̫Lɮɧ̫ҌЕȼ͈xǠ ƎѸϱijϬǯyʵїҌЕƊϬƠ̇ɞ̫ƎѸϱijŠR̀ 10.33 ěR̀ 10.34 ȁ͈˕DZ Šʔlʑ5 9.6 ωΌ1 ̫R̀ 9.50 ěR̀ 9.51Ѷ(ϬyɌ̫R̀ɽ˸ ʠҲϬ‚Ѣǃ̫yɌ R̀ 10.33 yɌ̛Ȁ˕žϥÞ̫ҌЕȼ͈xǠƎѸϱij 385 app/views/users/new.html.erb <% provide(:title, 'Sign up') %>

    Sign up

    <%= form_for(@user) do |f| %> <%= render 'shared/error_messages', object: f.object %> . . . <% end %>
    ij 10.11 ɯ͈ɽµƶǎàϥÞ̫ӊҹ/ R̀ 10.34 yɌΠщ̛ȀϥÞ̫ҌЕȼ͈xǠƎѸϱij app/views/users/edit.html.erb <% provide(:title, "Edit user") %>

    Update your profile

    386 ͩ 10 ͥ ̛Ȁ̫ǎà
    <%= form_for(@user) do |f| %> <%= render 'shared/error_messages', object: f.object %> . . . <% end %> <%= gravatar_for(@user) %> change
    ̓Ĵȁɽ̫˜ЍưВѹþTѫѐ5 $ bundle exec rspec spec/ ήʄω˦Ê̫ȁɽ HTML R̀0ѹιʵ͆˪ʘ ij 10.11 ɯ͈5µƶǎà̫ϥÞij 10.12 ɯ͈5ɽ  ҌЕȼ͈xǠ̫ϥÞ̓ĴlþTοƜòƞ ͳǎàЍ  °ɮčѹþTʵƤѓϡѐɼşіɮĴ 10.3.3 ω* ĊŸЍĎ 387 ij 10.12 ɯ͈ɽҌЕȼ͈xǠ̫ӊҹ 10.3.3 ÎûM©DĮ 10.3.2 ωѲ̢5 Éιˎɽų̓ ӊҹˎɽɯ͈ÌǙŠʔlǴDZ̫ЏþTĴij 10.11 ȁ͈̫ϥÞ òϥ ͳ ć˓̫ǎà˼Ċт»̛ȀЬəҹҷӎЈ їϥÞɮčþTʵƤn̛їʠĴҹҷ*ҖʌʌĬĬɮɽ˸Ӗ˻ ̫ŠʔιĴӊҹɯ͈ ďɽǃĄ̀‘̛Ȁ̫ǎà²ϥƊş5ʐǜijŠij 10.13 ȁ͈Ĵͩ 11 ͥ ǻU_ Ĵїǎà²ϥ ʑǃĄ̀‘̛Ȁȁ–˕̛Ȁ̫ǎà ij 10.13 ɯ͈ɽ#ɩÌǙ²ϥ̫ӊҹʐǜij ĭ$ʿ̛ȀѹưВɽ ÌǙ²ϥĭʶǻUþTĴ User ʬľ Ų) ĉ$ feed ̫ɟ˓ͪÉι’Ѹų̓ ĊǻU_˜Ѝǎà²ϥ ɮčÓď5ȁ–˕̛Ȁ̫ǎàѐ̓ĴǻUüҲϬ˜Ѝ feed ɟ˓̫ѕĬ~ɮčüɽ ǃĄ̀‘̛Ȁ̫ǎàήˎɽ˜P̛Ȁ̫ǎà˜ЍȁҲ̫R̀ŠR̀ 10.35 ȁ͈ R̀ 10.35 ž#ɩÌǙ²ϥ̫˜Ѝ spec/models/user_spec.rb require 'spec_helper' 388 ͩ 10 ͥ ̛Ȁ̫ǎà describe User do . . . it { should respond_to(:microposts) } it { should respond_to(:feed) } . . . describe "micropost associations" do before { @user.save } let!(:older_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) end let!(:newer_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago) end . . . describe "status" do let(:unfollowed_post) do FactoryGirl.create(:micropost, user: FactoryGirl.create(:user)) end its(:feed) { should include(newer_micropost) } its(:feed) { should include(older_micropost) } its(:feed) { should_not include(unfollowed_post) } end end end ѝR̀Ĵɕ΍Л̛5 include? ɟ˓Ń: RSpec žƞƆ~ɟ˓̫·ŲВɟ˓̫k̛ɮʨʙɕ΍ ɮč ÓďȦŲ̫‹΁ 9 $ rails console >> a = [1, "foo", :bar] >> a.include?("foo") => true >> a.include?(:bar) => true 9. ǻ*ȁTĴ 1.1.1 ω ȹϐЙέĴЙŰʄ2ĊҘЙ ʄΉKΑ Ruby ̫2Ɗɮ$5ŭ1n̛Ͷb include? їʠ̫ɟ˓ 389 >> a.include?("baz") => false їʼR̀Зɪ5 RSpec žƞƆ~ɟ˓̫·ŲɮŐ(̫˶˘ϝ˼ include ɮ Ruby ДϷ̫–ҎƯ̄ʌƼ‘ʬ ĻĴR̀ 8.14 ɽ̛»cĴǃÀДŇ RSpec q˼ιʵ̫͆ЉºǻU̫DZijɮϬ˜Ѝɕ΍ɮčÓď5ȦŲ ̫‹΁ ĴΠ¢ feed ɟ˓ɩǻUҲϬMɕȰƯ ó¬ȁɽ user_id ͪ:ǃÀ̛Ȁ id ̫ǎàϬĴ Micropost žП Л̛ where ɟ˓ŠR̀ 10.36 ȁ͈10 R̀ 10.36 ÌǙ²ϥ̫¶ʷų̓ app/models/user.rb class User < ActiveRecord::Base . . . def feed # This is preliminary. See "Following users" for the full implementation. Micropost.where("user_id = ?", id) end . . . end Micropost.where("user_id = ?", id) ̫ҕĂþT͆w id ̫~Ĵ`‘ƱƏ̫ SQL ʙБДú*À‚5Ѣ ǃ̫т)ѵ“SQL ˕‘”ї͑ѿ̫ů’ҪǤїѾ̛»̫ id ƓǝɮɗɕˎH(äҧѐĴ SQL Дú Ƽ‘õҀ*À‚т)ɮş1ǭ ΎǏ̫ЙέþιƝΒ˕DZ»5̓ҜʼR̀ 10.36 ̫R̀ěҷ̫Ų)k̛ɮ ʠ̫ def feed microposts end ǻU*ȁTn̛5R̀ 10.39 ̫̂ʄɮĭ$Ůιɹş̫ɿË:ͩ 11 ͥ ų̫̓Űɗ̫ÌǙ²ϥ Ϭ˜ЍÌǙ²ϥ̫ɯ͈ǻUӊϬµƶ Aǎà˼Ċʨ˜ĆǎàĴҹҷ ɮčĹÓďĴ²ϥ‹΁ li ŠR ̀ 10.37 ȁ͈ R̀ 10.37 ˜Ѝӊҹɯ͈̫ǎà²ϥ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do 10. ҘЙ Rails Ȧß ̫Active Record Query Interface ɘɹˤ‘̫ŭ1 where ͪɟ˓̛̫˓ 390 ͩ 10 ͥ ̛Ȁ̫ǎà subject { page } describe "Home page" do . . . describe "for signed-in users" do let(:user) { FactoryGirl.create(:user) } before do FactoryGirl.create(:micropost, user: user, content: "Lorem ipsum") FactoryGirl.create(:micropost, user: user, content: "Dolor sit amet") sign_in user visit root_path end it "should render the user's feed" do user.feed.each do |item| expect(page).to have_selector("li##{item.id}", text: item.content) end end end end . . . end R̀ 10.37 €Іȁɯ͈̫ʿͳǎàѹɽġ ̫ CSS idȁTŠR̀ expect(page).to have_selector("li##{item.id}", text: item.content) _$ʿǎà̚Ǻ ÖѺĩ˕DZli##{item.id} ̫ͩ  # ɮ Capybara ̫žư CSS id ̫ú˓ή ͩ9 # ³Rϥ Ruby Ūͨ"Ƚ~Ɉk #{} ̫Ʒţ ϬĴ͈o͘Ʈ n̛ÌǙ²ϥǻUþTĴ home Ìk Ų)  @feed_items ųoõҀŠR̀ 10.38 ȁ͈ ˼ĊŸĴӊҹìϮR̀ 10.41 ʑ ÌǙ²ϥƎѸϱijìϮR̀ 10.39ž¯ҹ̫˜Ѝ_̢kΌ1 ìϮ 10.5 ω R̀ 10.38 Ĵ home Ìk ʑ ųoõҀ app/controllers/static_pages_controller.rb class StaticPagesController < ApplicationController def home if signed_in? 391 @micropost = current_user.microposts.build @feed_items = current_user.feed.paginate(page: params[:page]) end end . . . end R̀ 10.39 ÌǙ²ϥƎѸϱij app/views/shared/_feed.html.erb <% if @feed_items.any? %>
      <%= render partial: 'shared/feed_item', collection: @feed_items %>
    <%= will_paginate @feed_items %> <% end %> ÌǙ²ϥƎѸϱijn̛ŠR̀ȏ²ϥһ̴̫˪ʘɊѺΖ5 feed_item ƎѸϱij <%= render partial: 'shared/feed_item', collection: @feed_items %> ǻU`‘5 ĉ$ :collection ̫ìɕ˜~$ @feed_itemsїʠ render ɟ˓Ɗ_ĴȦŲ̫ƎѸϱij ʄo ̫ feed_itemn̛їүć ̫ɕȰ˪ʘĆһ̴*ÀĴ˪ʘƎѸϱijɩǻUѹ̹̣5 :partial ìɕoŠ render 'shared/micropost'ѐŠʔȦŲ5 :collection ìɕї̛̹̣̫͑˓ ƊɮҌЕ̫²ϥһ̴ƎѸϱij̫R̀ŠR̀ 10.40 ȁ͈ R̀ 10.40 ˪ʘÞÌǙ²ϥһ̴̫ƎѸϱij app/views/shared/_feed_item.html.erb
  • <%= link_to gravatar_for(feed_item.user), feed_item.user %> <%= link_to feed_item.user.name, feed_item.user %> <%= feed_item.content %> Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
  • R̀ 10.40 іn̛Š̫R̀$ʿÌǙһ̴ȦŲ5 CSS id
  • їʵɮR̀ 10.37 ̫˜ЍȁϬʨ˜̫ 392 ͩ 10 ͥ ̛Ȁ̫ǎà ě*À ʠǻUþTȏÌǙ²ϥƎѸϱijʑӊҹʌɯ͈ÌǙŠR̀ 10.41 ȁ͈ʑĊ̫ɐʔƊɮĴӊҹɯ ͈5ÌǙ²ϥěӀʁ ʠŠij 10.14 ȁ͈ R̀ 10.41 Ĵӊҹ ʑÌǙ²ϥ app/views/static_pages/home.html.erb <% if signed_in? %>
    . . .

    Micropost Feed

    <%= render 'shared/feed' %>
    <% else %> . . . <% end %> ij 10.14 ɯ͈5#ɩÌǙ²ϥ̫ӊҹ/ 393 ̓Ĵòƞɞǎà̫ÉιþTȧ˽ӀʁʵƤƘk5Šij 10.15 ȁ͈ѐіɽƄƄз ŠʔòƞǎàŗХ ӊҹі_ҲϬ ĉ$ @feed_items ̫ųoõҀȁTȼBŗХɩΤͤƊɣ˓ʵƤѓϡ5l0þTѓϡ˜Ѝʌ ӎЈ ɼͮÞ̫ϵ¤ɟ˓ɮŠʔȼBŗХƊȏ @feed_items І$͝ɕ΍ŠR̀ 10.42 ȁ͈11 ij 10.15 òƞɞǎàĊ̫ӊҹ R̀ 10.42 Ĵ create Ìkʑ ̫͝ @feed_items ųoõҀ app/controllers/microposts_controller.rb class MicropostsController < ApplicationController . . . def create @micropost = current_user.microposts.build(micropost_params) if @micropost.save flash[:success] = "Micropost created!" redirect_to root_url else @feed_items = [] render 'static_pages/home' end 11. NjƬїʠ̫Џ¯ҹƊþ̛5lþTʑ¯ҹ˸­¯ҹ҈ȷ̺ ɮ$H( 394 ͩ 10 ͥ ̛Ȁ̫ǎà end . . . end πʶ#ɩ̫ÌǙ²ϥþTʵƤƘk5˜Ѝ΍V0þTѫѐ5 $ bundle exec rspec spec/ 10.3.4 GŬ¦S ǻUϬ$ Microposts Ьˬų̫̓ɼĊ Éιɮ·Ҧǎàě·Ҧ̛ȀͶbìϮ 9.4.2 ω·Ҧǎà0ɮѫѐ “delete”҈ȷų̫̓ʐǜijŠij 10.16 ȁ͈·Ҧ̛ȀϬҤ¼üɽͰ̕ĕȃιјϡή·Ҧǎà̫҈ȷüžǎà̫ òƞέþ̛ ij 10.16 ɯ͈ɽ·Ҧ҈ȷ̫#ɩÌǙ²ϥʐǜij 395 ͩ ʷǻUϬĴǎàƎѸϱijR̀ 10.21 ʑ·Ҧ҈ȷĈɩіϬĴÌǙ²ϥһ̴̫ƎѸϱijR̀ 10.40 ʑͶb̫҈ȷΔʔŠR̀ 10.43 ěR̀ 10.44 ȁ͈їƎѸϱijŃʄɮ ʠ̫˟ҦR̀ѿ Ŏ_̢kΌ1ìϮ 10.5 ω R̀ 10.43 ĴǎàƎѸϱij ʑ·Ҧ҈ȷ app/views/microposts/_micropost.html.erb
  • <%= micropost.content %> Posted <%= time_ago_in_words(micropost.created_at) %> ago. <% if current_user?(micropost.user) %> <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" }, title: micropost.content %> <% end %>
  • R̀ 10.44 ĴÌǙ²ϥһ̴ƎѸϱij ʑ·Ҧ҈ȷ app/views/shared/_feed_item.html.erb
  • <%= link_to gravatar_for(feed_item.user), feed_item.user %> <%= link_to feed_item.user.name, feed_item.user %> <%= feed_item.content %> Posted <%= time_ago_in_words(feed_item.created_at) %> ago. <% if current_user?(feed_item.user) %> <%= link_to "delete", feed_item, method: :delete, data: { confirm: "You sure?" }, title: feed_item.content %> <% end %>
  • ž·Ҧǎà̫˜ЍϬ̛ Capybara ʌ˸­“delete”҈ȷ˼Ċʨ˜ǎà̫ɕҀɮč§ƅ5 ŠR̀ 10.45 ȁ͈ R̀ 10.45 ҂ž Microposts ȸ¼ĩ destroy Ìk̫˜Ѝ spec/requests/micropost_pages_spec.rb require 'spec_helper' describe "Micropost pages" do . . . 396 ͩ 10 ͥ ̛Ȁ̫ǎà describe "micropost destruction" do before { FactoryGirl.create(:micropost, user: user) } describe "as correct user" do before { visit root_path } it "should delete a micropost" do expect { click_link "delete" }.to change(Micropost, :count).by(-1) end end end end ͘ƮȁҲ̫R̀іɮěR̀ 9.47 ·Ҧ̛ȀɩͶb͑ǧ¥̫%ϬĈ*Ōɮ·Ҧǎàn̛ admin_user 8Àѐ˰ĩ5ήɮ̛ correct_user 8Àѐ˰ĩʨʙǃÀ̛Ȁɮčòƞ5ȦŲ id ̫ǎàŠR̀ 10.46 ȁ ͈ij 10.17 ɯ͈̫ɮ·Ҧ5zɕͩ9ǎàĊ̫ҹҷ R̀ 10.46 Microposts ȸ¼ĩ̫ destroy Ìk app/controllers/microposts_controller.rb class MicropostsController < ApplicationController before_action :signed_in_user, only: [:create, :destroy] before_action :correct_user, only: :destroy . . . def destroy @micropost.destroy redirect_to root_url end private def micropost_params params.require(:micropost).permit(:content) end def correct_user @micropost = current_user.microposts.find_by(id: params[:id]) redirect_to root_url if @micropost.nil? end end ˕DZĴ correct_user 8Àѐ˰ĩ ǻUɮѫѐ–γ–΀ʙſǎà̫ current_user.microposts.find_by_id(params[:id]) 397 їϡR̀þTοϡ͆wüĴǃÀ̛Ȁòƞ̫ǎà ʙБїѾǻUn̛̫ɮ find_byήˎ̛ findĭ$Šʔ ˎɽȌ»ǎà find _Ȓ¬ƸƤή_ѕĬ nilҼtЗ Šʔl1ǭŌ̕ Ruby ƸƤ0þTȧ˽ҷ̫ ɟƻŲ) correct_user ѐ˰ĩ def correct_user @micropost = current_user.microposts.find(params[:id]) rescue redirect_to root_url end lþι_ЗǻU0þT̶ȷn̛ Micropost žПʌų̓ correct_user ѐ˰ĩƊˆҷїʠ @micropost = Micropost.find_by(id: params[:id]) redirect_to root_url unless current_user?(@micropost.user) ї͑ų̓ɟƻŃʄěR̀ 10.46 ɮ ʠ̫ѐWolfram Arnold ĴAccess Control 101 in Rails and the Citibank Hack ɘ ϵѽѐů’гϮɼşіɮѫѐ–γʌʙȌ ij 10.17 ·Ҧ5zɕͩ9ͳǎàĊ̫ӊҹ ʑ5ʄω̫R̀ĊǻU̫ Micropost ʬľTî̛Ȁ̠ҷƊѹŰǺ5˜Ѝ΍V0þTѫѐ5 398 ͩ 10 ͥ ̛Ȁ̫ǎà $ bundle exec rspec spec/ 10.4 ŒĘ ʑ5 Microposts ЬˬĊǻU̫͈o͘ƮŃʄŰǺ5іˎų̫̓Ѹ¯ɮ͉BÉιϽ̛Ȁ*ҖþT̷=– ˕Ĵͩ 11 ͥ ǻU_ŭ1Šhų̓ї͑–γ–΀іϬų̓ ̻ʵ̫ÌǙ²ϥ Šʔln̛ Git ‚̂ʄȸ¼̫ЏĴΚΛ*ÀȼBɌÌ˼ĊŸćƫ»%¯Ɋ $ git add . $ git commit -m "Add user microposts" $ git checkout master $ git merge user-microposts $ git push ̓Ĵl0þTȏ͘Ʈȹѡ» Heroku ĭ$ʑ microposts ϥɌÌ5ɕȰʬľĭʶlҲϬĴ“̚CɕȰƯ” Ȇϡю͗Ɉk $ git push heroku $ heroku pg:reset DATABASE $ heroku run rake db:migrate $ heroku run rake db:populate 10.5 Ė »̴À$ʴǻUƝΒų̓5NjŐÉιĴ̓ɽÉι̫Ń̈́ǻUіþTų̓ɹŐ̫ÉιҷƊɮ Aoũ 1. ˦ʘЍʨ˜rьʞ ǎà̫ɕҀɮčʵ͆ɯ͈5ϬÓďžÞŎɕ̫ʨʙ 2. ˦ʘЍʨ˜ǎà̫¯ҹÉι 3. ѿʐӊҹ̫ϱijɘVȏ if-else Дú̫¯Ɋ¯ºɎ»Þ̫̌ƎѸϱij  4. Π¢ ˜Ѝ͆wɮǃÀ̛Ȁòƞ̫ǎàɟ_ɯ͈·Ҧ҈ȷ 5. n̛ƎѸϱijëȳR̀ 10.43 ěR̀ 10.44 ̫ѿŎ 6. ̓Ĵ̆ºґ̫ÞЋ_Ʉ͂ƞƎŠij 10.18 ȁ͈n̛R̀ 10.47 Ų)̫ wrap ƣÍɟ˓yʵїҌ Е˕DZ˜ ̛»̫ raw ɟ˓ɮ$5ѵ Rails т) HTML R̀sanitize ɟ˓ɮ$5қʴлͤμʄ ɍ­їʼR̀і̛»5̺гʌNjŚǞcɮNjų̛̫‹Ɉkͨternary operatorìϮɡ˕ 10.1 ̫З ɪ 7. ҟÊӄĴӊҹ ˦Ê ʼ JavaScript R̀ǃĴòƞǎà̫ϥÞ ъ‘ɘŪɩɯ͈ъ‘̫Ź 140 Ū̫ͨƛ~ 399 Íå 10.1ă ̠ɽ͑G ͑ħʮ̛‹Ɉkͨ ͑ħʮіɽ ̙͑π̾ѱ‹ɈkͨɮH(Šʔl Ƭɮͩ͑G̫Џ̺ѐҷ̫ЗɪƊŸǂƓ˜ 5 ĴΠ¢NjŐR̀*Ċl_ò̓ɼƤ̛»̫˚͘ȸ¼ɮͶbҷї͑ if boolean? do_one_thing else do_something_else end Ruby ě˜PNjŐДϷ ʠÓȠ C/C++PerlPHP ě Javaȼp5 ͑ɹ$ͮÞ̫ϥэƻʌɻȮї͑˚͘ ȸ¼Δʐ——‹Ɉkͨ*ȁTг5їĉŪɮĭ$‹ɈkͨˠîѸ¯ boolean? ? do_one_thing : do_something_else ‹Ɉk̙ͨπþT̛ʌɻRЭ~Ɉk if boolean? var = foo else var = bar end þTɌ¢Ǻ var = boolean? ? foo : bar ûŏ ΒƤn̛ĵɟɮĴ®ɕ̫ѕĬ~ def foo do_stuff boolean? ? "bar" : "baz" end ĭ$ Ruby ®ɕ̫әϻѕĬ~ɮŲ)g ̫ɼĊ ϥэƻȁT foo ɟ˓̫ѕĬ~_ʢȰ boolean? ̫Δʔ ήĈɮ "bar" Ɗɮ "baz"R̀ 10.47 Ɗ̛»5ї͑Δʐ R̀ 10.47 Ȯϡɯ͈ґÞЋ̫ƣÍɟ˓ app/helpers/microposts_helper.rb 400 ͩ 10 ͥ ̛Ȁ̫ǎà module MicropostsHelper def wrap(content) sanitize(raw(content.split.map{ |s| wrap_long_string(s) }.join(' '))) end private def wrap_long_string(text, max_width = 30) zero_width_space = "​" regex = /.{1,#{max_width}}/ (text.length < max_width) ? text : text.scan(regex).join(zero_width_space) end end ij 10.18 ̆ºґ̫ÞЋɄ͂5Τ̫ͤƞƎ 401 ʶҹ̢̩ ͩ 11 ͥ –˕̛Ȁ ĉ 11 ć :åö® Ĵї ͥ ǻU_Ĵ̓ɽ͘Ʈ̫Ń̈́ňÊ͉BÉιŠЄ̛Ȁ–˕followǼó˟–˕˜PGƫĴ̛Ȁ% ҹɯ͈˜ȁ–˕̛Ȁ̫ǎàɹɞǻUі_µƶҹҷ̛ʌɯ͈–˕̛̫Ȁ²ϥěͷ²ϥǻUƃ_Ĵ 11.1 ωŭ1Šhʐƶ̛Ȁ*Җ̫ʬľ–΀ҩĊĴ 11.2 ωІϹΤҹ̠ҷĈɩі_KΑ AjaxɼĊǻU_Ĵ 11.3 ω ų̓ Űɗ̫ÌǙ²ϥ їɮʄ2ɼĊ ͥ˜ _Óď5 Aʄɓ͘ ɼ™ɽȨǽǝ̫Ź$5ų̓ÌǙ²ϥǻU_n̛ A Ruby/ SQL ƄȎƚ ѫѐїAoũl_5ϵ» Rails ɮŠhŌ̕ɹÊŎʇ̫ɕȰʬľ̫ήїA̾Љ_ĴlɥĊƷò˜ Pư̛ɩòȩk̛ $5ƣÍlƩ͚ĵMɓ͘ŭ1ѐ˩»̌͢ƷòĴ 11.4 ωǻUȹϐ5©þTĴƝɽǎàʡ ǏŃ̈́Ʒò̫ӆŏÉιTî AјҜЬə̫҈ȷ ě*Àͥω ʠGit ̛ȀưВµƶ ɞ̫¯Ɋ $ git checkout -b following-users ĭ$ʄ̫ͥŹˀчɽȨǽǝĴƷţΠ¢R̀*ÀǻUʌǜά Τ̫̠ͤҷ ě*À̫ͥω ʠĴƷò ̫ɨʁҜʼǻU_ѫѐʐǜijʌē̓ҹҷ1Űɗ̫ҹҷ˚͘ɮїʠ̫ ĉ̛Ȁ (John Calvin) MP̫GЬəҹҷ Šij 11.1 ˝ϲ»̛Ȁ΂ƼҹҷŠij 11.2–˕5 ̛ȀCalvin ȄƷû ̛Ȁ Thomas Hobbes ̫G %ҹŠij 11.3˸­“Follow–˕”ȧ҄ –˕В̛Ȁ˼Ċї“Follow”ȧ҄_õ$“Unfollowó˟– ˕” ή Hobbes ̫–˕Gɕ_ňÊ 1 Šij 11.4ȷ̽Calvin Ĭ»οƜ̫%ҹ̺»–˕GɕňÊ5 1 ĴÌǙ²ϥ 0ι̺» Hobbes ̫̉ǙɹɞŠij 11.5ȷʌ̫ɗͥŹƊɮϬų̓їʠ̫ҹҷ˚͘ 11.1 :đàs $5ų̓–˕̛Ȁї Éιͩ ʷǻUϬ‚̫ɮµƶ ̺ëƫɮѶ(̶ϯ̫ɕȰʬľ ƷţǻUþι_ ϻ$  has_many ̫ɕȰ–΀ι˯зǻU̫Ϭˇ ̛ȀþT–˕Ơ̋ȀĈɩ ̛ȀіιϧƠ̋Ȁ– ˕cųҠї͑–΀ɮūĴҕӄ̫ҷǻUƊʌŭ1Šhn̛ has_many through ʌϵ¤їҕӄʄωNj ŐÉι̫ų̓¶̺гʌѹɽ˸ҭT̕ϵlҲϬϊ ˸ɩҖǜάȃι̻ʵɀ˧ʪїʠ‚̫êĭŠʔĴʗĵɟ âf5ƉЍ̽LjĊЙ˼ĊŸȏʄωЙ Ѱ̺ ´ȃâf̫ĵɟǯɪ̩5ˎ 11.1.1 Ç·às—Öûũŷ&Wĵ@Ì¡ ʐѭɕȰʬľ̫ͩ ʷǻUʌ̺ šľ̫ǧ¥€Š ̛Ȁ–˕5ûŏ ̛ȀˀŠ Calvin –˕5 Hobbes0Ɗɮ Hobbes ϧ Calvin –˕5Ѷ( Calvin Ɗɮ–˕έfollowerή Hobbes ³ɮϧ–˕έ( followed )ȧ˽ Rails әϻ̫Ŏɕϥ͈1ǭ ǻU͖–˕ʗ ̆Ų̛Ȁ̛̫Ȁүć$В̛Ȁ̫ followers 1. ʐǜij ̫؈ʌο http://www.flickr.com/photos/john_lustig/2518452221 ě http://www.flickr.com/photos/30775272@N05/ 2884963755 403 user.followers ƊɮїA̛Ȁ΍Ǻ̫ɕ΍ѐǃǻUӇz ҼƮѝ–΀³Ǻ͢5 әϻǧ¥ ȁɽϧ–˕̛̫Ȁ͖$ followedsїʠЗĴύДД˓ƫѫҼǡǃǻUþT͖ϧ–˕έ$ followingcїЋ ɽAʹ) ĴύДѾ”following” Ȧ–˕l̫GěǻUǯϥэ̫ǡǡ̷ñάϛ»ѝ͑ǧ¥ƌͰǻUƃn ̛“following”k$ʜͭŠ“50 following, 75 followers”, cĴɕȰʬľ _n̛“followed users”ϥ͈ǻU–˕̛̫Ȁ үćTî žư̫ user.followed_users ɕ΍2 ij 11.1 ǃĄ̀‘̛Ȁ̫GЬəҹҷ Βѐѝ̫ϼЅǻU_ȧ˽ij 11.6 ̫ɟƻʐƶϧ–˕̛Ȁ̫ʬľn̛ followed_users ϥų̓ žŐ (has_many)–γ̜: user.followed_users ưВɮ ̛ȀžП΍Ǻ̫ɕ΍ȁT followed_users ϥ ̫ʿ ϡưВžư ̛ȀƫȦŲ followed_id ²ě˜P̛Ȁƶ͢–γ3Ҧʶ*ŏ̜:ʿ ϡĹžư ̛ȀȁTǻUіϬĴϥ ʑ̛Ȁ̫˜PƓǝÓȠĉŪź̀ͪ ij 11.6 Ȼѝ̫ɕȰʬľLūĴ ҕӄѶƊɮūĴҵƤŐ̫¡iʿ ϡIÓȠ5ȁ–˕̛Ȁ̫ id, іÓȠ 5PU̫˜PxǠήїAxǠĴ users ϥ ѹɽ ɹͿͽ̫ɮ$5ƶ͢–˕̛Ȁ̫ɕȰʬľǻUіҲϬ 2. Ĵʄ2ͩ ̂ n̛5 user.following cǻò̓ɽɩЙгʌdzϳǞǞ̫dzНЙέ Cosmo Lee ЗɿǻyɌїϥѝ ƫƶϿǻŠhn˜̕ϵгʌɹŹɫA(ѐǻƫˎɽےѼΊP̫ƶϿȁTŠʔlҘЙɩLdz»ўǩИϬǞP) 3. $5ͮÞ˧ɳij 11.6 ˎɽɯ͈ followed_users ϥ̫ id ² 404 ͩ 11 ͥ –˕̛Ȁ Þ̫̌Ĉʠ¡i̫ followers ϥїɼΐƃƀρɕȰʬľʏҭΜȓʿǃ̛ȀyɌŤĉɩǻUIϬyɌ ̛ȀĴ users ϥ ̫ɕȰіϬyɌ followed_users ě followers ϥ žưВ̛Ȁ̫ʿ ЁDŽ ij 11.2 ſȌ ̛Ȁʌ–˕ ѭǺїҕӄ̫%ϬêĭɮǻUΣƅ5 ƏȗП Ȍ»ćѢȗП̫ ɟ˓ɮǜάǻU_ŠhĴư̛͘Ʈ ų ̓–˕̛Ȁ̫ɈkĴ 7.1.2 ω ǻUKΑѐREST ʖʐˠƶЬˬě҉ʽЬˬѐ͘ ̜ʶƼ¬ҕ ӄ ǃ̛Ȁ–˕û ̛Ȁɩµƶ5H( ǃ̛Ȁó˟–˕û ̛Ȁɮ҉ʽ5H( ȧ˽ REST ʖʐ̫ǜмŸʭǜά*ĊǻU_ò̓Ĵ–˕̛Ȁ̫ѐ͘ ϧµƶěϧ҉ʽ̫ɮ̛Ȁ*Җ̫“– ΀”Ĵї͑“–΀”  ̛ȀɽŐ“–΀”has_many :relationshipsƫɽNjՖ˕̛̫Ȁ followed_users Ǽ followers)˜ųĴij 11.6 ǻUƝΒŃʄų̓5ї͑“–΀” ̜:ʿ ϧ–˕̫ ̛Ȁѹɮ̜ followed_id ̌ ɣ9̫ʜЉ¬ʌ̫ǻUƊþTƃ followed_users ϥтÔǺ relationships ϥ·ȳ̛Ȁ̫ГΎЬən̛ followed_id M users ϥ ϓnjϧ–˕̛Ȁ̫ɕȰ Ĉʠ̫ї͑“–΀”ñѐ ʌǻUþTn̛ follower_id ϓóȁɽͷ΍Ǻ̫ɕ΍ $5nj» ̜ȁɽϧ–˕̛Ȁ΍Ǻ̫ followed_users ɕ΍ǻUþTϓó̜ followed_id Ɠǝ΍Ǻ̫ɕ ΍ŸʙȌʿ̛ȀѐŠlȁǯRails $ǻUȼp5 ͑ɹͮÞ̫ɟƻѶƊɮ has_many throughǻ UƃĴ 11.1.4 ωKΑ Rails ŠЄǻUn̛ҷїϡ˧ɳͮ˖̫R̀ѫѐ relationships ϥʌȻѝ ̛Ȁ– ˕5Nj՘P̛Ȁ 405 has_many :followed_users, through: :relationships, source: "followed_id" їϡR̀_οÌϓóϧ–˕̛Ȁ΍Ǻ̫ɕ΍0Ɗɮ user.followed_users ij11.7 Ȼѝ5їɕȰʬľ ij 11.3 ǯϬ–˕̛̫ȀЬəҹҷɯ͈ɽ–˕ȧ҄ ҷϽǻUÌȂų̓ӊǻUѫѐҷ̫ĚSµƶ Relationship ʬľ $ rails generate model Relationship follower_id:integer followed_id:integer їĚSþι_̚Ǻ Relationship ӀʐVlưВƃ˜·Ҧ $ rm -f spec/factories/relationship.rb ̜:ǻUҲѫѐ follower_id ě followed_id ʌʙƠ̏Ȁ*Җ̫–΀άϛ»ǝιϬ$ї²Ê΂Ƽ Š R̀ 11.1 ȁ͈ R̀ 11.1 Ĵ relationships ϥ ІΦ΂Ƽ db/migrate/[timestamp]_create_relationships.rb 406 ͩ 11 ͥ –˕̛Ȁ class CreateRelationships < ActiveRecord::Migration def change create_table :relationships do |t| t.integer :follower_id t.integer :followed_id t.timestamps end add_index :relationships, :follower_id add_index :relationships, :followed_id add_index :relationships, [:follower_id, :followed_id], unique: true end end ij 11.4 –˕ȧ҄õ$ó˟–˕̫Ĉɩ–˕GɕňÊ5 1  ĴR̀ 11.1 ǻUіІΦ5 ΍ć΂Ƽcomposite index˜̴̫ɮ͆w (follower_id, followed_id) ΍ćɮġ ̫їʠ̛ȀƊɣ˓Őʭ–˕Ĉ ̛Ȁ5 (þTěR̀ 6.19 $wȥ Email ĵĸġ ̫ index ‚ˀч ) 407 add_index :relationships, [:follower_id, :followed_id], unique: true M 11.1.4 ωƷţǻU_ò̓Ĵ̛Ȁ̠ҷ їʠ̫8ǧɮ_ò̫̚cɮ˦Ê5΍ć΂ƼĊŠʔ̛ȀЍij9 ʭ–˕ɩ͘Ʈ_Ȓ¬ƸƤoŠn̛ˆ curl їʠ̫ĚSϡ͘ƮǻU0þTĴ Relationship ʬľ ˦Êġ ǝɕȰӎЈcĭ$ʿʭƉЍµƶ ѿŎ–΀ɩѹ_϶òҌЕȁTї΍ć΂Ƽ̓ĴƝΒι˯зǻU̫Ҳˇ 5 ij 11.5 G%ҹ¬̓5ɞ–˕̛Ȁ̫ǎà–˕GɕňÊ5 1  ij 11.6 ͮÞ̛̫Ȁ=̷–˕ų̓ 408 ͩ 11 ͥ –˕̛Ȁ ij 11.7 ѫѐ relationships ϥƶ̫͢ϧ–˕̛ȀɕȰʬľ $5µƶ relationships ϥě*À ʠǻUϬȆϡɕȰƯю͗Ÿ¦ōş“˜ЍɕȰƯ” $ bundle exec rake db:migrate $ bundle exec rake test:prepare nj»̫ Relationship ɕȰʬľŠij 11.8 ȁ͈ ij 11.8 Relationship ɕȰʬľ 11.1.2 User h Relationship àsŪû:ĥ Ĵ̽Ȃų̓Ɲ–˕̛Ȁě–˕έ*ÀǻUϬƶ͢ User ě Relationship ʬľ*Җ̫–γ–΀ ̛ȀþTɽŐ “–΀”has_many relationships, ĭʶ “–΀”ˠî»̛ȀȁTї“–΀”ƊĈɩƓ: belongs_toВ̛Ȁěϧ–˕έ ě 10.1.3 ωµƶǎà ʠǻUƃѫѐ User ě Relationship ʬľ*Җ̫–γʌµƶї“–΀”n̛Š̫R̀ų ̓ user.relationships.build(followed_id: ...) ӊǻUʌΠ¢˜ЍŠR̀ 11.2 ȁ͈ R̀ 11.2 ˜Ѝƶ͢“–΀”TîƓǝ̫þЇҕǝ 409 spec/models/relationship_spec.rb require 'spec_helper' describe Relationship do let(:follower) { FactoryGirl.create(:user) } let(:followed) { FactoryGirl.create(:user) } let(:relationship) { follower.relationships.build(followed_id: followed.id) } subject { relationship } it { should be_valid } end їѾҲϬ˕DZ˜Ѝ User ě Micropost ʬľɩn̛ @user ě @micropost ĈR̀ 11.2 n̛ let Rɻ5 ųoõҀї͑ɟƻ*Җ©+ˎɽƛº4cǻϻ$n̛ let ̷ž:n̛ųoõҀɹɫǷ˜Ѝ User ě Micropost ɩ*ȁTn̛ųoõҀɮơʀЙέɨAȷ϶їѿϬ̫ʫǖή let ³̣ɯӑˤȁTǻUɎĴїѾȃ̛ ĈɩĴ User ʬľ ǻUіϬ˜Ѝ̛ȀžПɮčþTĞư relationships ɟ˓ŠR̀ 11.3 ȁ͈ R̀ 11.3 ˜Ѝ user.relationships spec/models/user_spec.rb require 'spec_helper' describe User do . . . it { should respond_to(:feed) } it { should respond_to(:relationships) } . . . end ʶɩlþι_ǯĴ͘Ʈ ʑͶb: 10.1.3 ω ̛»̫R̀ǻUϬ˦Ê̫R̀͆ųNjˆc9έ*Җɽ Ō Nj ʠ Ĵ Micropost ʬľ  ǻUn̛ class Micropost < ActiveRecord::Base belongs_to :user . . . end 4. ИĴ Stack Overflow ΤͤҘЙ–:“hɩưn̛ let ɟ˓”̫ϼЅʌ5ϵɹ՝Ź 410 ͩ 11 ͥ –˕̛Ȁ ě class User < ActiveRecord::Base has_many :microposts . . . end ĭ$ microposts ϥ ūɽ user_id ƓǝþTʜ̛͈ȀìϮ 10.1.1 ωї͑ћȷɕȰϥ̫ idǻU͖ *$ŏҎforeign keyǃȦċ User ʬľ̫ŏҎ$ user_id ɩRails Ɗ_οÌ̫ϓ̾–γ–΀ĭ$әϻǧ¥ Rails _ſȌ _id Džƻ̫ŏҎ˜ ɮʬľͶĉ̫Ƅ¢Džƻ5̓ĴƌͰǻUŌ̫̕іɮ ̛ȀcŏҎɮ follower_id 5ȁTǻUϬĔЊ Rails ї õÔŠR̀ 11.4 ȁ͈6 R̀ 11.4 ų̓ User ě Relationship ʬľ*Җ has_many ̫–γ–΀ app/models/user.rb class User < ActiveRecord::Base has_many :microposts, dependent: :destroy has_many :relationships, foreign_key: "follower_id", dependent: :destroy . . . end ̜:·Ҧ̛ȀĊ0ưВ·ҦВ̛Ȁ̫ȁɽ“–΀” :ɮǻUȦŲ5 dependent: :destroy ìɕ ҂ž·Ҧ ɐʔ̫˜Ѝ_̢kΌ1ìϮ 11.5 ω ě Micropost ʬľ ʠRelationship ʬľě User ʬľ*Җ0ɽ Ə belongs_to –΀ʶɩї͑–΀ĈɩƓ: –˕έěϧ–˕έ҂žїƏ“–΀”̫˜ЍŠR̀ 11.5 ȁ͈ R̀ 11.5 ˜Ѝ User ě Relationship ʬľ*Җ̫ belongs_to –΀ spec/models/relationship_spec.rb describe Relationship do . . . describe "follower methods" do it { should respond_to(:follower) } it { should respond_to(:followed) } its(:follower) { should eq follower } its(:followed) { should eq followed } 5. ʣʌЗRails ɮn̛ underscore ɟ˓ȏͶĉтȮ$ id ̫oŠ"Foobar".underscore ̫Δʔɮ "foo_bar"ȁ T Foobar žП̫ŏҎɮ foo_bar_idҼtЗ underscore ̫ѤɈkɮ camelizeїɟ˓_ȏ "camel_case" тȮǺ "CamelCase" 6. Šʔl˕DZ» followed_id ĈʠþTʜЉ̛ȀƫȘǏїϵ¤ɟ˓_ѭǺϧ–˕έěͷ*ҖūĴҵž͖̫–΀, lƝ Βǯ»ǻU̫Àҷ5ǻU_Ĵ 11.1.5 ωϵ¤їҕӄ 411 end end ҷǻUƷţ¢͘Ʈ̫R̀belongs_to –΀̫ƶ͢ě*À ʠRails _ѫѐ Symbol ϓ̾ŏҎ̫ĉŪo Š:follower žư̫ŏҎɮ follower_id:followed žư̫ŏҎɮ followed_idc Followed Ǽ Follower ʬľɮūĴ̫ĭʶїѾƊϬn̛ User їͶĉ ŠR̀ 11.6 ȁ͈˕DZәϻ̚Ǻ̫ Relationship ʬľĈїѾüɽ followed_id ɮþTЇҕ̫ R̀ 11.6 $ Relationship ʬľ˦Ê belongs_to –΀ app/models/relationship.rb class Relationship < ActiveRecord::Base belongs_to :follower, class_name: "User" belongs_to :followed, class_name: "User" end ƌͰ̶» 11.1.5 ωǻUȃ_̛» followed –γcĈɩų̓ follower ě followed –γ_ɹŹɫ̕ϵ ʶɩR̀ 11.2 ěR̀ 11.3 ̫˜ЍưВþTѫѐ5 $ bundle exec rspec spec/ 11.1.3 Ç·źľ ĴΔʉїѸ¯*ÀǻUƃ˦Ê A҂ž Relationship ʬľ̫ɕȰӎЈ͆wR̫̀Űɗǝ˜ЍR̀ 11.7ě ͘ƮR̀R̀ 11.8ѹҵƤɫǷ R̀ 11.7 ˜Ѝ Relationship ʬľ̫ɕȰӎЈ spec/models/relationship_spec.rb describe Relationship do . . . describe "when followed id is not present" do before { relationship.followed_id = nil } it { should_not be_valid } end describe "when follower id is not present" do before { relationship.follower_id = nil } it { should_not be_valid } end end R̀ 11.8 ˦Ê Relationship ʬľɕȰӎЈ app/models/relationship.rb 412 ͩ 11 ͥ –˕̛Ȁ class Relationship < ActiveRecord::Base belongs_to :follower, class_name: "User" belongs_to :followed, class_name: "User" validates :follower_id, presence: true validates :followed_id, presence: true end 11.1.4 į:åûö® ҷ»5 Relationship –γ–΀̫ʡǏѸ¯5ϓó followed_users ě followers ǻUӊM followed_users Ʒţ˜ЍŠR̀ 11.9 ȁ͈ R̀ 11.9 ˜Ѝ user.followed_users Ɠǝ spec/models/user_spec.rb require 'spec helper' describe User do . . . it { should respond_to(:relationships) } it { should respond_to(:followed_users) } . . . end ų̫̓R̀_ͩ ʭn̛ has_many through ̛Ȁѫѐ relationships ϥȞɽŐ–˕–΀Ɗˆij 11.7 ȁ ͈̫Ѷʠәϻǧ¥Ĵ has_many through –γ Rails _ſȌ–γĉÞɕDžƻžư̫ŏҎ0ƊɮЗˆ ҷ̫R̀ has_many :followeds, through: :relationships _n̛ relationships ϥ ̫ followed_id ²̚Ǻ ɕ΍cɮʵŠĴ 11.1.1 ω Зѐ̫ user.followeds ї͑З˓ˀчрμϋn̛“followed users”k$ “followed”̫ŎɕDžƻ_şnjŐѶ(ϧ–˕̫ ̛Ȁɕ΍ƊϬ¢Ǻ user.followed_users 5Rails ǃ˼_ŠЄǻUѿ¢әϻ̫ІΦ҂žʄoǻUþTn̛ :source ìɕìϮR̀ 11.10Ĕ̾ Rails followed_users ɕ΍̫ʌˬɮ followed ȁRϥ̫ id үć R̀ 11.10 Ĵ User ʬľ ˦Ê followed_users –γ app/models/user.rb class User < ActiveRecord::Base has_many :microposts, dependent: :destroy has_many :relationships, foreign_key: "follower_id", dependent: :destroy has_many :followed_users, through: :relationships, source: :followed . 413 . . end $5µƶ–˕–γ–΀ǻUƃŲ) ĉ$ follow! ̫ɟ˓їʠǻUƊιn̛ user.follow!(other_user) їʠ̫R̀µƶ–˕5follow! ɟ˓ưВ create! ě save! ɟ˓ ʠ ŗХɩȒ¬ƸƤȁTǻUĴĊҷÊ5dzĄĂžưĵǻUі_˦Ê  following? ƞƆ~ɟ˓ʨʙ ̛Ȁɮč–˕5û ̛Ȁ7R̀ 11.11 ̫˜Ѝϥɪ5ǻUơʀŠhn̛їɟ˓ R̀ 11.11 ˜Ѝ–˕–΀̛»̫ɟ˓ spec/models/user_spec.rb require 'spec_helper' describe User do . . . it { should respond_to(:followed_users) } it { should respond_to(:following?) } it { should respond_to(:follow!) } . . . describe "following" do let(:other_user) { FactoryGirl.create(:user) } before do @user.save @user.follow!(other_user) end it { should be_following(other_user) } its(:followed_users) { should include(other_user) } end end Ĵų̫̓R̀ following ɟ˓ȷô ̛ȀžПk$ìɕìɕĉ$ other_userʨʙїϧ–˕έ̫ id ĴɕȰƯ ɮčūĴ follow! ɟ˓̶ȷЛ̛ create! ɟ˓ѫѐě Relationship ʬľ̫–γʌµƶ–˕–΀ ŠR̀ 11.12 ȁ͈ R̀ 11.12 Ų) following? ě follow! ɟ˓ app/models/user.rb 7. ǃlȞɽĴʗӁŁœҀƶ͢ʬľ̫ΒӎĊǟιȼÀ̎»їʠ̫Ƙ™ɟ˓Šʔˎɽ̎»̫Џ0ΒƤιò̓οƜÌȂ¢ї ʠ̫ɟ˓þTn˜ЍR̀ɹÊɗ˖ʶɩŠʔlˎɽ̎»ŮU̫Џ0NjʵƤфVƷòΒƤɮ ǍƮ˨ј̫ѐ͘lŀŘ Π¢R̀ò̓R̀Nj4ɩŸѿʐ c$5ϡɘͮ˖ʄ2Ѽó̫ɮ̶ȯӗӝ̫ɟ˓ 414 ͩ 11 ͥ –˕̛Ȁ class User < ActiveRecord::Base . . . def feed . . . end def following?(other_user) relationships.find_by(followed_id: other_user.id) end def follow!(other_user) relationships.create!(followed_id: other_user.id) end . . . end ˕DZĴR̀ 11.12 ǻUỤ̈́5̛ȀžПοс̶ȷ¢Ǻ relationships.create!(…) ήɮͪɐ̫ self.relationships.create!(…) ɮčn̛ self –ҎŪüɮGşήƝ ǃ˼̛ȀưВɤι–˕0ιó˟–˕Ѷ(іưВɽ  unfollow! ɟ˓ŠR̀ 11.13 ȁ͈8 R̀ 11.13 ˜Ѝó˟–˕̛Ȁ spec/models/user_spec.rb require 'spec_helper' describe User do . . . it { should respond_to(:follow!) } 8. 8ų unfollow!ɟ˓ĴŗХɩ_Ȓ¬ƸƤǻ̙π̾ѱ Rails ɮŠhϥɪ·ҦɈkŗХ̫ѐ$5ě follow! wȥ ρǻUіɮÊ5dzĄĂ 415 it { should respond_to(:unfollow!) } . . . describe "following" do . . . describe "and unfollowing" do before { @user.unfollow!(other_user) } it { should_not be_following(other_user) } its(:followed_users) { should_not include(other_user) } end end end unfollow! ɟ˓̫Ų)NjŹɫ̕ϵѫѐ followed_id Ȍ»žư̫“–΀”·ҦƊϡ5ŠR̀ 11.14 ȁ͈ R̀ 11.14 ·Ҧ“–΀”ó˟–˕̛Ȁ app/models/user.rb class User < ActiveRecord::Base . . . def following?(other_user) relationships.find_by(followed_id: other_user.id) end def follow!(other_user) relationships.create!(followed_id: other_user.id) end def unfollow!(other_user) relationships.find_by(followed_id: other_user.id).destroy end . . . end 11.1.5 Đ –˕–΀̫ɼĊ Ѹ¯ɮŲ)ě user.followed_users ̷žư̫ user.followers ɟ˓Mij 11.7 lǼЄò ̓5ϓóͷɕ΍ȁҲ̫ɕȰѹƝΒū‘ relationships ϥ 5їѾǻƯ»̫ɟ˓ěų̓ϧ–˕έɩ 416 ͩ 11 ͥ –˕̛Ȁ ʠüϬžЛ follower_id ě followed_id ̫dΦåþїЗɪ üϬǻUžЛї²̫dΦ΍ƶǺ reverse_relationships ϥŠij 11.9 ȁ͈user.followers ɟ˓̫Ų)ƊNjŹɫ5 ij 11.9 n̛zтĊ̫ Relationship ʬľϓóͷ ǻUʌΠ¢˜Ѝ̷x͋Ś̫ Rails ƃŸ ʭɯ̓ťÇŠR̀ 11.15 ȁ͈ R̀ 11.15 ˜ЍžЛĊ̫–˕–΀ spec/models/user_spec.rb require 'spec_helper' describe User do . . . it { should respond_to(:relationships) } it { should respond_to(:followed_users) } it { should respond_to(:reverse_relationships) } it { should respond_to(:followers) } . . . describe "following" do . . . it { should be_following(other_user) } its(:followed_users) { should include(other_user) } describe "followed user" do 417 subject { other_user } its(:followers) { should include(@user) } end . . . end end ˕DZ ѝR̀ ǻUɮŠhn̛ subject ʌтõ˜ЍžП̫ǻUM @user т»5 other_user˼Ċ ǻUƊιn̛ҷҷї͑Njο˼̫ɟƻ˜Ѝͷ ɮčÓď @user 5 subject { other_user } its(:followers) { should include(@user) } lþιƝΒǯ»5ǻU_Ÿƶ͢ Űɗ̫ɕȰϥʌūɎzтĊ̫–˕–΀8ųǻU_ѫѐϧ–˕έě ͷ*Җ̫ž͖–΀ʌʬȝ  reverse_relationships ϥ%ҎІ$ followed_id0ƊɮЗ relationships ϥn̛ follower_id ‚ŏҎ has_many :relationships, foreign_key: "follower_id" Ѷ(reverse_relationships ϜȝϥƊ̛ followed_id ‚ŏҎ has_many :reverse_relationships, foreign_key: "followed_id" ͷ̫–γƊƶ͢ĴїƏñт̫–΀ŠR̀ 11.16 ȁ͈ R̀ 11.16 ѫѐñт̫–΀ų̓ user.followers app/models/user.rb class User < ActiveRecord::Base . . . has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship", dependent: :destroy has_many :followers, through: :reverse_relationships, source: :follower . . . end ěR̀ 11.4 ʠ҂ž dependent :destroy ̫˜Ѝ_̢kΌ1ìϮ 11.5 ω ˕DZ$5ų̓ɕȰϥ*Җ ̫–γǻUϬȦŲͶĉ 418 ͩ 11 ͥ –˕̛Ȁ has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship" ŠʔˎɽȦŲͶĉRails _ƉЍſȌ ReverseRelationship ͶήїͶƫūĴ іɽ ˸~nj˕DZ ĴѾǻU˜ųþT̹̣ :source ìɕn̛ҷ̫ͮÞɟƻ has_many :followers, through: :reverse_relationships ž :followers ƓǝήϷRails _ȏ“followers”тǺÞɕDžƻοÌſȌĉ$ follower_id ̫ŏҎĴʶǻw ̢5 :source ìɕɮ$5wȥ has_many :followed_users –΀*ҖΔʐ̫ž͖l0þTѥȟëȳ Ů ʑR̀ 11.16 *Ċ–˕έěͷ*Җ̫–γƊŰǺ5ȁɽ̫˜ЍưВѹþTѫѐ5 $ bundle exec rspec spec/ 11.2 :åö®KħûĠŲøű Ĵʄ̫ͥƀϷ ǻUKΑ5–˕̛ȀÉι̫Ɉk˚͘ʄωǻU_ų̓їAʐǜ̫Ńʄ̠ҷTî–˕ěó˟– ˕ɈkĈɩǻUі_µƶҹҷ¯º²¬–˕̛̫ȀěͷĴ 11.3 ω ǻU_ʑ̛Ȁ̫ÌǙ²ϥ˜ ɩї͈o͘ƮȃͯŰǺ 11.2.1 ö®:åöHûā.Ç· ě*À̫©ͥ ʠǻU_n̛ Rake XË̚Ǻ͈oɕȰċɕȰƯ ū‘#ɩ̛̫Ȁ–˕–γɕȰɽ5їA͈ oɕȰǻUƊþTƷòΤҹήȏĊͦÉι̫ų̓ɎĴʄω̫ɼĊ ǻUĴR̀ 10.20 ̛»̫͈oɕȰ̚Ǻĩɽ˸4ȁT̓ĴǻUϬ¯ºŲ)ɟ˓̛ʌ̚Ǻ̛Ȁěǎà͈o ɕȰ˼ĊŸŲ) make_relationships ɟ˓̚Ǻ̛Ȁ–˕–γɕȰŠR̀ 11.17 ȁ͈ R̀ 11.17 ʑ̛Ȁ–˕–γ͈oɕȰ lib/tasks/sample_data.rake namespace :db do desc "Fill database with sample data" task populate: :environment do make_users make_microposts make_relationships end end def make_users admin = User.create!(name: "Example User", 419 email: "example@railstutorial.org", password: "foobar", password_confirmation: "foobar", admin: true) 99.times do |n| name = Faker::Name.name email = "example-#{n+1}@railstutorial.org" password = "password" User.create!(name: name, email: email, password: password, password_confirmation: password) end end def make_microposts users = User.all(limit: 6) 50.times do content = Faker::Lorem.sentence(5) users.each { |user| user.microposts.create!(content: content) } end end def make_relationships users = User.all user = users.first followed_users = users[2..50] followers = users[3..40] followed_users.each { |followed| user.follow!(followed) } followers.each { |follower| follower.follow!(user) } end ̛Ȁ–˕–γ̫͈oɕȰɮ̜ҷ̫R̀̚Ǻ̫ def make_relationships users = User.all user = users.first followed_users = users[2..50] followers = users[3..40] followed_users.each { |followed| user.follow!(followed) } followers.each { |follower| follower.follow!(user) } end ǻU̫ůȵɮҩʆ̫Ͻͩ 1 ̛Ȁ–˕ͩ 3 »ͩ 51 ̛ȀŸϽͩ 4 »ͩ 41 ̛Ȁ–˕ͩ 1 ̛ȀDžǺ5ї ʠ̛̫Ȁ–˕ΤƊзŒ̛ʌƷò͘Ʈ̫̠ҷ5 420 ě*À ʠϬǯѓϡR̀ 11.17ƊϬȆϡҷ̫ɕȰƯĚS $ bundle exec rake db:reset $ bundle exec rake db:populate $ bundle exec rake test:prepare ͩ 11 ͥ –˕̛Ȁ 11.2.2 ÇţĚķh:åĮR ̓Ĵ̛ȀƝΒɽ–˕̫Gěͷ5ǻUϬɹɞ ̛ȀЬəҹҷěӊҹȏїAõÌɯ͈¬ʌӊǻUϬµ ƶ –˕ěó˟–˕̫ϥÞ˼ĊŸµƶɯ͈ϧ–˕̛Ȁ²ϥěͷ²ϥ̫ҹҷ ǻUĴ 11.1.1 ω Зѐ“following”їЋk$Ɠǝĉɮɽ˸ŚǞ̫ĭ$ user.following ɤþT̕ϵ$ϧ– ˕̛̫Ȁ0þT̕ϵ$–˕̛̫ȀcþTk$ʜͭn̛oŠþTЗ“50 following”˜ųTwitter Ɗn̛ 5ї͑ʜͭDžƻij 11.1 ̫ʐǜijˑ̛5ї͑ϥѝїѸ¯ГΎ̫ʐǜŠij 11.10 ȁ͈ ij 11.10 ɕҀΙϹƎѸϱij̫ʐǜij ij 11.10 ɯ͈̫ɕҀΙϹÓď5ǃÀ̛Ȁ–˕̛̫Ȁě–˕5В̛Ȁ̫ͷɕ9έí¯º҈ȷ»5ĆοГΎ̫ ̛Ȁ²ϥҹҷĴͩ 5 ͥ ǻUn̛ # ádͨRɻ̻ų̫Τĸĭ$ѶɩǻUіˎǚ(ȷ϶м̜̓Ĵϝ˼Ĵ 11.2.3 ω ȃ_µƶȁҲ̫ҹҷѐǻUþTІΦм̜ŠR̀ 11.18 ȁ͈їʼR̀Ĵ resources Ļ n̛ 5 :member ɟ˓TÀˎ̛ѐlþT̎˜ їɟ˓̫k̛ɮH(˕DZR̀ 11.18 ɮ̛ʌɻȮêʌ̫ resources :users ̫ R̀ 11.18 ȏ following ě folloers Ìkʑ Users ȸ¼ĩ̫м̜ config/routes.rb SampleApp::Application.routes.draw do resources :users do member do get :following, :followers end end . . . end lþι̎»5ІŲѝм̜Ċnj»̫ URL ĵĸưВɮͶb /users/1/following ě /users/1/followers ї͑Džƻ ҌR̀ 11.18 ̫k̛͆ųŠʶĭ$їҹҷѹɮ̛ʌɯ͈ɕȰ̫ȁTǻUn̛5 get ɟ˓ȦŲїĵ ĸĞư̫ɮ GET Иˇͨć REST ʖʐžї͑ҹҷ̫Ϭˇм̜ІΦ n̛̫ member ɟ˓k̛ɮІΦї Ìkžư̫ URL ĵĸ ưВÓď̛Ȁ̫ idͶbĵǻUіþTn̛ collection ɟ˓c URL Ɗˎɽ ̛Ȁ id 5ȁTŠ̫R̀ 421 resources :users do collection do get :tigers end end ІŲм̜Ċnj»̫ URL ɮ /users/tigersþT̛ʌɯ͈͘Ʈ ȁɽ̫ΫϚ–:м̜̫ї͑ІΦɹГΎ̫Зɪ þTҘЙ Rails Ȧß ̫Rails Routing from the Outside In ɘR̀ 11.18 ȁ̚Ǻ̫м̜Šϥʣ 11.1 ȁ͈И̢ DZ ϧ–˕̛Ȁěͷҹҷ̫™ĉм̜ɮH(͙ĊǻU_̛»$5ѵ̛Ћ˥ˡĴ“following”м̜ ǻU ˎɽn̛“followed users”ї͑З˓ήˑ̛5 Twitter ̫ɟƻѼ̛“following”їЋĭ$“followed users” ї̛͑ ˓_̚Ǻ followed_users_user_path ї͑ŚǞ̫™ĉм̜Šϥʣ 11.1 ȁ͈ǻUѥȟn̛“following”ї Ћĭʶnj»̫™ĉм̜ɮ following_user_path ϥʣ 11.1 R̀ 11.18 ІΦ̫м̜̚Ǻ̫ REST м̜ HTTP Иˇ URL Ìk ™ĉм̜ GET /users/1/following following following_user_path(1) GET /users/1/followers followers followers_user_path(1) Іş5м̜ĊǻUʌΠ¢žɕҀΙϹƎѸϱij̫˜ЍêʄǻUþT¢˜Ѝ̫cɮŠʔˎʑȁҲ̫м̜ ІΦþιɣMȂΠ¢˜ЍɕҀΙϹƎѸϱij_¬̓Ĵ̛ȀЬəҹҷěӊҹ R̀ 11.19 üžӊҹјϡ5 ˜Ѝ R̀ 11.19 ˜Ѝӊҹ ɯ͈̫–˕ěͷɕҀΙϹ spec/requests/static_pages_spec.rb require 'spec_helper' describe "Static pages" do . . . describe "Home page" do . . . describe "for signed-in users" do let(:user) { FactoryGirl.create(:user) } before do FactoryGirl.create(:micropost, user: user, content: "Lorem") FactoryGirl.create(:micropost, user: user, content: "Ipsum") sign_in user visit root_path end 422 ͩ 11 ͥ –˕̛Ȁ it "should render the user's feed" do user.feed.each do |item| expect(page).to have_selector("li##{item.id}", text: item.content) end end describe "follower/following counts" do let(:other_user) { FactoryGirl.create(:user) } before do other_user.follow!(user) visit root_path end it { should have_link("0 following", href: following_user_path(user)) } it { should have_link("1 followers", href: followers_user_path(user)) } end end end . . . end ѝ˜Ѝ̫ʡǏɮʨ˜ҹҷ ɮčɯ͈5–˕ěͷɕTîɮčȦċ5ʵ̫͆ĵĸ it { should have_link("0 following", href: following_user_path(user)) } it { should have_link("1 followers", href: followers_user_path(user)) } ǻƯ»5ϥʣ 11.1 ̫™ĉм̜ʌ˜Ѝ҈ȷɮčȦċ5ʵ̫͆ĵĸіɽ ŌϬ˕DZ їѾ̫“followers”ɮ k$ʜͭn̛̫ȁTǻU_ ̶̛ŎɕDžƻånüɽ ͷ0ɮŠʶ ɕҀΙϹƎѸϱij̫R̀NjͮÞĴ  div ‹΁ ɯ͈©҈ȷƊϡ5ŠR̀ 11.20 ȁ͈ R̀ 11.20 ɯ͈–˕ɕҀΙϹ̫ƎѸϱij app/views/shared/_stats.html.erb <% @user ||= current_user %> ĭ$їƎѸϱij_ĈɩĴ̛ȀЬəҹҷěӊҹ ɯ͈ȁTĴR̀ 11.20 ̫ͩ ϡ ǻUϬϓóʵ̛̫͆Ȁž П <% @user ||= current_user %> ǻUĴɡ˕ 8.2 KΑѐїʠ̛̫˓Šʔ @user ɮ nilĴ̛ȀЬəҹҷїϡR̀ƊˎH(ɐʔήŠʔ ɮ nilĴӊҹ Ɗ_ȏǃÀ̛ȀžПЭ~Ζ @user іɽ Ō0Ϭ˕DZ –˕ɕҀěͷɕҀɮѫѐ–γϓó̫¯ºn̛ @user.followed_users.count ě @user.followers.count ǻUþTěR̀ 10.17 ϓóǎàɕҀ̫R̀žˀ ǎà̫ɕҀɮѫѐ @user.microposts.count ϓó̫ ɼĊіɽ AΎωҲϬ˕DZѶƊɮʗA‹΁̫ CSS idoŠ ... їA id ɮ$ 11.2.5 ω ų̓ Ajax ÉιɿË̫Ajax _ѫѐ̌ ɣ9̫ id ϓóҹҷ ̫‹΁ Πş5ƎѸϱijȏŮɎ‘ӊҹ ƊNjͮÞ5ŠR̀ 11.21 ȁ͈ʑƎѸϱijĊR̀ 11.19 ̫˜Ѝ0Ɗ _ѫѐ5 R̀ 11.21 Ĵӊҹ ɯ͈̫–˕ěͷɕҀΙϹ app/views/static_pages/home.html.erb <% if signed_in? %> . . .
    <%= render 'shared/user_info' %>
    <%= render 'shared/stats' %>
    <%= render 'shared/micropost_form' %>
    . 424 ͩ 11 ͥ –˕̛Ȁ . . <% else %> . . . <% end %> ǻU_˦Ê A SCSS R̀ʌΨÔ ɕҀΙϹѸ¯ŠR̀ 11.22 ȁ͈їʼR̀Óď5ʄ̛ͥ»̫ȁɽʠ ƻ˦ÊʠƻĊ̫ҹҷŠij 11.11 ȁ͈ R̀ 11.22 ӊҹrьʞ̫ SCSS ʠƻ app/assets/stylesheets/custom.css.scss . . . /* sidebar */ . . . .stats { overflow: auto; a{ float: left; padding: 0 10px; border-left: 1px solid $grayLighter; color: gray; &:first-child { padding-left: 0; border: 0; } &:hover { text-decoration: none; color: $blue; } } strong { display: block; } } .user_avatars { overflow: auto; margin-top: 10px; 425 .gravatar { margin: 1px 1px; } } . . . ij 11.11 ɯ͈5–˕ɕҀΙϹ̫ӊҹ ͙ĊǻUŸȏɕҀΙϹƎѸϱijʑ̛ȀЬəҹҷ̓ĴʌΠ¢–˕ěó˟–˕ȧ̫҄ƎѸϱijŠR̀ 11.23 ȁ͈ R̀ 11.23 –˕ěó˟–˕ϥÞ app/views/users/_follow_form.html.erb <% unless current_user?(@user) %>
    <% if current_user.following?(@user) %> <%= render 'unfollow' %> <% else %> <%= render 'follow' %> <% end %> 426 ͩ 11 ͥ –˕̛Ȁ
    <% end %> їʼR̀˜ų0ˎ‚H(üɮȏ™g̫Ƙk¯ѺΖ follow ě unfollow ƎѸϱij5їʠǻUƊϬŸʭІΦм ̜ʑ Relationships Ьˬì˽ Microposts Ьˬ̫ІΦìϮR̀ 10.25ŠR̀ 11.24 ȁ͈ R̀ 11.24 ˦Ê Relationships Ьˬ̫м̜ІΦ config/routes.rb SampleApp::Application.routes.draw do . . . resources :sessions, only: [:new, :create, :destroy] resources :microposts, only: [:create, :destroy] resources :relationships, only: [:create, :destroy] . . . end follow ě unfollow ƎѸϱij̫R̀¯ºŠR̀ 11.25 ěR̀ 11.26 ȁ͈ R̀ 11.25 –˕̛Ȁ̫ϥÞ app/views/users/_follow.html.erb <%= form_for(current_user.relationships.build(followed_id: @user.id)) do |f| %>
    <%= f.hidden_field :followed_id %>
    <%= f.submit "Follow", class: "btn btn-large btn-primary" %> <% end %> R̀ 11.26 ó˟–˕̛Ȁ̫ϥÞ app/views/users/_unfollow.html.erb <%= form_for(current_user.relationships.find_by(followed_id: @user), html: { method: :delete }) do |f| %> <%= f.submit "Unfollow", class: "btn btn-large" %> <% end %> їϥÞѹn̛5 form_for ʌŌ̕ Relationship ʬľžП9έ*Җ%Ϭ̫Ĉ˸ɮR̀ 11.25 ̫R̀ɮ ʐƶ ɞ̫“–΀”ήR̀ 11.26 ɮʙȌ̓ɽ̫“–΀”Njɯ˼ͩ ϥÞ_ċ Relationships ȸ¼ĩòѡ POST Иˇµƶ“–΀” ήͩ9ϥÞòѡ̫ɮ DELETE Иˇ҉ʽ“–΀”ϥÞ̛»̫Ìk_Ĵ 11.2.4 ωΠ ¢lþιі˕DZ»5їϥÞ Ҧ5ȧ҄*ŏH(Ź0ˎɽcɮіϬ`ѡ followed_idǻU_Л ̛ hidden_fields ɟ˓ƃ˜Ê‘̚Ǻ̫ HTML Š Ҫϙ̫ input ϥÞŁ_ȏȁҲ̫xǠÓďĴϥÞ cɮĴ˝ϲĩ _ɯ͈¬ʌ 427 ̓ĴǻUþTĴҹҷ ʑ–˕ϥÞě–˕ɕҀΙϹ5üҲ˪ʘ̷ư̫ƎѸϱijåþŠR̀ 11.27 ȁ͈Ĵ̛ ȀЬəҹҷ ʢȰųҠ̫–˕ǧ¥_¯ºɯ͈–˕ȧ҄Ǽó˟–˕ȧ҄Šij 11.12 ěij 11.13 ȁ͈ ij 11.12 ɯ͈5–˕ȧ̛̫҄ȀЬəҹҷ/users/2 R̀ 11.27 Ĵ̛ȀЬəҹҷʑ–˕ϥÞě–˕ɕҀΙϹ app/views/users/show.html.erb <% provide(:title, @user.name) %>
    <%= render 'follow_form' if signed_in? %> . 428 ͩ 11 ͥ –˕̛Ȁ . .
    ͙ĊǻU_ϽїAȧ҄гk̛ήǻU_n̛͑ų̓ɟƻ ͑ɮƤϰɟƻ11.2.4 ωû ͑ɮn̛ Ajax ̫ɟƻ11.2.5 ωѐĴʶ*ÀǻUϬŰǺ̛Ȁ̠ҷ̫¼kµƶɯ͈–˕̛̫Ȁ²ϥěͷ²ϥ̫ҹҷ 11.2.3 :åDĮhĐ DĮŲű ɯ͈–˕²ϥěͷ²ϥ̫ҹҷŃʄɮѿ΍̛Ȁ̫Ьəҹҷě̛Ȁ΂ƼҹҷìϮ 9.3.1 ωĴrьʞ ɯ͈ ̛Ȁ̫xǠÓȠ–˕ɕҀΙϹŸ²¬̛Ȁ²ϥҦʶ*ŏі_Ĵrьʞ ɯ͈ ̛̜Ȁ̫؈΍Ǻ̫ʛ ʣʐǜijŠij 11.14–˕̫Gěij 11.15ͷUȁ͈ ӊǻUϬϽїҹҷ̫ĵĸþЇҕȧ˽ Twitter ̫ɟƻЇҕїҹҷѹҲϬ̨DŽ˜ЍŠR̀ 11.28 ȁ̛͈Ą̏DŽĊҹҷ ưВ¯ºɯ͈–˕̛̫Ȁ²ϥěͷ²ϥ˜ЍŠR̀ 11.29 ȁ͈ R̀ 11.28 ˜Ѝ–˕²ϥěͷ²ϥҹҷ̫ЇҕʈҤІΦ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do describe "for non-signed-in users" do let(:user) { FactoryGirl.create(:user) } describe "in the Users controller" do . . . describe "visiting the following page" do before { visit following_user_path(user) } it { should have_title('Sign in') } end describe "visiting the followers page" do before { visit followers_user_path(user) } it { should have_title('Sign in') } end end . 429 . . end . . . end . . . end R̀ 11.29 ˜Ѝ–˕²ϥěͷ²ϥҹҷ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . . . describe "following/followers" do let(:user) { FactoryGirl.create(:user) } let(:other_user) { FactoryGirl.create(:user) } before { user.follow!(other_user) } describe "followed users" do before do sign_in user visit following_user_path(user) end it { should have_title(full_title('Following')) } it { should have_selector('h3', text: 'Following') } it { should have_link(other_user.name, href: user_path(other_user)) } end describe "followers" do before do sign_in other_user visit followers_user_path(other_user) end it { should have_title(full_title('Followers')) } it { should have_selector('h3', text: 'Followers') } it { should have_link(user.name, href: user_path(user)) } 430 end end end ͩ 11 ͥ –˕̛Ȁ ij 11.13 ɯ͈5ó˟–˕ȧ̛̫҄ȀЬəҹҷ/users/6 Ĵїҹҷ̫ų̓ѐ͘ ġ ŌNjҭǯ»̫ĵɟɮϬDZЉ»ǻUҲϬĴ Users ȸ¼ĩ ˦ÊÌkȧ ˽R̀ 11.18 м̜̫ІΦїÌk¯ºĉ$ following ě followersĴїÌk ҲϬІΦҹҷ̫ ʜӄʙБ̛Ȁ¯ºϓó @user.followed_users ě @user.followersϬ¯ҹɯ͈˼ĊŸ˪ʘҹ ҷŠR̀ 11.30 ȁ͈ R̀ 11.30 following ě followers Ìk app/controllers/users_controller.rb class UsersController < ApplicationController before_action :signed_in_user, only: [:index, :edit, :update, :destroy, :following, :followers] . . . def following @title = "Following" @user = User.find(params[:id]) 431 @users = @user.followed_users.paginate(page: params[:page]) render 'show_follow' end def followers @title = "Followers" @user = User.find(params[:id]) @users = @user.followers.paginate(page: params[:page]) render 'show_follow' end private . . . end ij 11.14 –˕²ϥҹҷ̫ʐǜij 432 ͩ 11 ͥ –˕̛Ȁ ij 11.15 ͷ²ϥҹҷ̫ʐǜij ˕DZĴїÌk ѹɪ̫͆Л̛5 render ɟ˓˪ʘ ĉ$ show_follow ̫ϱijȷʌǻUƊʌΠ¢ їϱijїÌk*ȁTn̛Ĉ ϱijɮĭ$͑ǧ¥̛»̫ ERb R̀ƛŐŠR̀ 11.31 ȁ͈ R̀ 11.31 ˪ʘ–˕²ϥěͷ²ϥ̫ show_follow ϱij app/views/users/show_follow.html.erb <% provide(:title, @title) %>

    <%= @title %>

    <% if @users.any? %>
      <%= render @users %>
    <%= will_paginate %> <% end %>
    їɩ˜ЍưВþTѫѐ5ҹҷ0ιʵƤɯ͈5Šij 11.16–˕̫Gěij 11.17ͷUȁ͈ ij 11.16 ɯ͈ǃÀ̛Ȁ–˕̫G 434 ͩ 11 ͥ –˕̛Ȁ ij 11.17 ɯ͈ǃÀ̛Ȁ̫ͷ 11.2.4 :å¶Ťû™IJ‡óÌ¡ µƶş5ϱijĊǻUƊϬϽ–˕ěó˟–˕ȧ҄гk̛5҂žїȧ̫҄˜Ѝ̛»5ʄɓ͘ KΑ̫NjŐ˜ ЍȎʅ0ɮžR̀ҘЙιÇ̫άżИϻ̻̫ҘЙR̀ 11.32̶»l̕ϵ5˜Ѝ̫ŹTî$H(ї(‚Ÿ ҘЙĊҷ̫ŹїʼR̀ ɽ ŌNjƄ̫ů’̤˱̺ lɮčιò͙̓ĊǻU_Зɪ˕DZ have_xpath ɟ˓ɮӑΈήǁœ̫ȎʅВɟ˓n̛ [XPath](http://en.wikipedia.org/wiki/XPath) ʙȌ XML ɘʦ0ÓȠ HTML5lþTȿ΂“XPath syntax” 5ϵɹ՝Ź R̀ 11.32 ˜Ѝ–˕ěó˟–˕ȧ҄ spec/requests/user_pages_spec.rb require 'spec_helper' describe "User pages" do . . . describe "profile page" do let(:user) { FactoryGirl.create(:user) } . . 435 . describe "follow/unfollow buttons" do let(:other_user) { FactoryGirl.create(:user) } before { sign_in user } describe "following a user" do before { visit user_path(other_user) } it "should increment the followed user count" do expect do click_button "Follow" end.to change(user.followed_users, :count).by(1) end it "should increment the other user's followers count" do expect do click_button "Follow" end.to change(other_user.followers, :count).by(1) end describe "toggling the button" do before { click_button "Follow" } it { should have_xpath("//input[@value='Unfollow']") } end end describe "unfollowing a user" do before do user.follow!(other_user) visit user_path(other_user) end it "should decrement the followed user count" do expect do click_button "Unfollow" end.to change(user.followed_users, :count).by(-1) end it "should decrement the other user's followers count" do expect do click_button "Unfollow" end.to change(other_user.followers, :count).by(-1) end describe "toggling the button" do 436 ͩ 11 ͥ –˕̛Ȁ before { click_button "Unfollow" } it { should have_xpath("//input[@value='Follow']") } end end end end . . . end ѝ҂ž–˕ěó˟–˕ȧ̫҄˜Ѝ˸­їȧ҄˼Ċʨ˜ɮč‚5Ѣǃ̫Ɉkų̓їȧ̫҄Ɉk ҲϬǯnjˤ‘ ˸ –˕ěó˟–˕̫ѐ͘ˠƶ“–΀”ě҉ʽ“–΀”0ƊɮЗϬĴ Relationships ȸ¼ĩ Ų) create ě destroy ÌkїƊɮǻUϬ‚̫ϝ˼üɽ̨DŽĊ̛̫Ȁȃι̺»–˕ěó˟–˕ȧ҄ ňÊ5 Əů’ȺɠcɮR̀ 11.32 ̫˜Ѝ̤Ǘ5 ч$ƱƏ̫ҕӄѶƊɮ create ě destroy Ìkʄ сüιϧ̨DŽĊ̛̫ȀЇҕїƊɮÀҷȼ»̫ů’̤˱R̀ 11.33 ̫˜Ѝ¯ºЛ̛ post ě delete ɟ˓̶ȷЇҕїÌkʨ˜ʂ̨DŽ̛̫ȀɮčιЇҕ̷ư̫Ìk R̀ 11.33 ˜Ѝ Relationships ȸ¼ĩ̫ЇҕҤ¼ spec/requests/authentication_pages_spec.rb require 'spec_helper' describe "Authentication" do . . . describe "authorization" do describe "for non-signed-in users" do let(:user) { FactoryGirl.create(:user) } . . . describe "in the Relationships controller" do describe "submitting to the create action" do before { post relationships_path } specify { expect(response).to redirect_to(signin_path) } end describe "submitting to the destroy action" do before { delete relationship_path(1) } specify { expect(response).to redirect_to(signin_path) } end end . 437 . . end end end ˕DZǻUǯŐŲ) ˎ̛̫ Relationship žПȁTĴ҂ž delete Иˇ̫˜Ѝ Ĵ™ĉм̜ ̶ȷ¢‘ 5 id ̫~ before { delete relationship_path(1) } їʠ̫R̀*ȁTɽɐɮĭ$͘ƮĴƉЍn̛ id ϓó“–΀”*ÀƊưВтċ»̨DŽҹҷ5 ιŒϽѝ˜Ѝѫѐ̫ȸ¼ĩR̀ʏ˜ͮÞǻUüҲϓnjƝΒ–˕Ǽǯ–˕̛̫ȀžП˼Ċn̷̛ư̫Ƙ™ɟ ˓–˕Ǽó˟–˕ƊþT5™g̫ų̓R̀ŠR̀ 11.34 ȁ͈ R̀ 11.34 Relationships ȸ¼ĩ app/controllers/relationships_controller.rb class RelationshipsController < ApplicationController before_action :signed_in_user def create @user = User.find(params[:relationship][:followed_id]) current_user.follow!(@user) redirect_to @user end def destroy @user = Relationship.find(params[:id]).followed current_user.unfollow!(@user) redirect_to @user end end MR̀ 11.34 ǻUιŒ̺¬$H(Àҷȼ»̫ů’̤˱ɮH(œҕӄĭ$Šʔʂ̨DŽ̛̫Ȁ̶ȷЇҕ5XDZ ÌkoŠn̛ĚSϡƘ™ curlcurrent_user ̫~Ɗɮ nilѶ(Ìk̫ͩ9ϡR̀Ɗ_Ȓ¬ƸƤnj »ҌЕȼ͈ή_͂ĺ͘ƮǼɕȰѐɼşіɮϬqҶїʠ̫Ō̕ɟƻĭʶǻUĴÀҷȃʑ5ӆŏ̫ ů’Ⱥɠ πʶɗ–˕ěó˟–˕̫ÉιƊѹų̓5Xh ̛ȀѹþT–˕Ǽó˟–˕û ̛Ȁ5lþTĴ͘Ʈ ˸­̷ư̫҈ȷʨʙ 0þTѓϡ˜ЍӎЈ  $ bundle exec rspec spec/ 438 ͩ 11 ͥ –˕̛Ȁ 11.2.5 :å¶Ťû Ajax ‡óÌ¡ ϝ˼Ĵ ƄωǻUЗѐ–˕̛Ȁ̫ÉιƝΒےų̓5cɮĴų̓̉Ǚ²ϥ*ÀіɽþTňǁ̫ĵɟlþ ιƝΒ˕DZ»5Ĵ 11.2.4 ω Relationships ȸ¼ĩ̫ create ě destroy ÌkɼĊѹѕĬ5 ƷţЇҕ̛̫ ȀЬəҹҷ0ƊɮЗ̛Ȁ A ˝ϲ5̛Ȁ B ̫Ьəҹҷ˸­–˕ȧ҄–˕̛Ȁ B˼Ċҹҷ_͢ӋтĬ»̛ Ȁ A ̫Ьəҹҷĭʶžїʠ̫ѐ͘ǻUƊɽ5 ̥ҕ $H(ϬŐ ʭҹҷтċĖ Ajax þTϵ¤ї̥ҕѫѐċɿËĩòѡƸʷИˇĴ½ɞҹҷ̫ǧ¥Ajax ƊþTɹɞҹҷѾ̫Ź9 ĭ$ĴϥÞ Ō̕ Ajax ИˇɮNjƤ̛̫ȎʅȁT Rails ȏų̓ Ajax ̫ѐ͘õnjNjͮÞ˜ų–˕ěó˟–˕ϥ ÞƎѸϱij̛‚œ̫ɌÌüϬȏ form_for ɌǺ form_for..., remote: trueRails Ɗ_οÌn̛ Ajax Ō̕ϥÞ510ɹɞĊ̫ƎѸϱijŠR̀ 11.35 ěR̀ 11.36 ȁ͈ R̀ 11.35 n̛ Ajax Ċ̫–˕̛ȀϥÞ app/views/users/_follow.html.erb <%= form_for(current_user.relationships.build(followed_id: @user.id), remote: true) do |f| %>
    <%= f.hidden_field :followed_id %>
    <%= f.submit "Follow", class: "btn btn-large btn-primary" %> <% end %> R̀ 11.36 n̛ Ajax Ċ̫ó˟–˕̛ȀϥÞ app/views/users/_unfollow.html.erb <%= form_for(current_user.relationships.find_by(followed_id: @user), html: { method: :delete }, remote: true) do |f| %> <%= f.submit "Unfollow", class: "btn btn-large" %> <% end %> ѝ ERb R̀̚Ǻ̫ HTML ˎH(şЗ̫ŠʔlşŚ̫ЏþT̺ ҷ̫͈o
    . . .
    MїʼR̀ ǻUþT̺»form ‹΁ ІΦ5 data-remote="true"їƓǝƊɮ̛ʌĔ̾ Rails ВϥÞþ Tn̛ JavaScript Ō̫̕Rails 3 ѴM5“ҵs‘ƻ JavaScript”ê³unobtrusive JavaScriptˎɽĴϱij ¢‘ɗ  JavaScript R̀Ĵ Rails *À̫̂ʄ æɮї(‚̫ήɮn̛5 ͮÞ̫ HTML Ɠǝ ɹɞϥÞĊǻUϬϽ Relationships ȸ¼ĩþTĞưѶ Ajax Иˇ҂ž Ajax ̫˜Ѝɽ˸ŎʇےþT¢ʄ2 5ѐǻUþTMR̀ 11.37 Ȃїʼ˜Ѝ n̛5 xhr ɟ˓ϥ͈“XmlHttpRequest”òѡ Ajax Иˇ 9. ĭ$ Ajax ɮ asynchronous JavaScript and XML ̫΢¢ȁTΒƤϧҌЕ̫Ȣ¢$“AJAX”ѐĴɼ¶KΑ Ajax ̫ɘͥ ѫ ͳѹȢ¢$“Ajax” 10. üɽǃ˝ϲĩđ̛ JavaScript ɩȃιʵƤn̛ѐþT^ҮңΈŠʔ̛͌5 JavaScript Ɗ_ȧ˽ 11.2.4 ω ̫ɟƻƘk 439 xhr ɟ˓ě*Àn̛̫ getpostpatch ě delete ɟ˓ɮͶb̫˼ĊŸʨʙòѡ Ajax ИˇĊcreate ě destroy Ìkɮčјϡ5ʵ̫͆ɈkŠʔϬ$œҀn̛ Ajax ̫͘ƮΠ¢Űɗ̫˜ЍИ5ϵ  Selenium ě Watir R̀ 11.37 ˜Ѝ Relationships ȸ¼ĩž Ajax Иˇ̫Ğư spec/controllers/relationships_controller_spec.rb require 'spec_helper' describe RelationshipsController do let(:user) { FactoryGirl.create(:user) } let(:other_user) { FactoryGirl.create(:user) } before { sign_in user, no_capybara: true } describe "creating a relationship with Ajax" do it "should increment the Relationship count" do expect do xhr :post, :create, relationship: { followed_id: other_user.id } end.to change(Relationship, :count).by(1) end it "should respond with success" do xhr :post, :create, relationship: { followed_id: other_user.id } expect(response).to be_success end end describe "destroying a relationship with Ajax" do before { user.follow!(other_user) } let(:relationship) { user.relationships.find_by(followed_id: other_user) } it "should decrement the Relationship count" do expect do xhr :delete, :destroy, id: relationship.id end.to change(Relationship, :count).by(-1) end it "should respond with success" do xhr :delete, :destroy, id: relationship.id expect(response).to be_success end 440 ͩ 11 ͥ –˕̛Ȁ end end R̀ 11.37 ɮǻUͩ ʭn̛ȸ¼ĩ˜Ѝcontroller testǻTÀΒƤn̛ȸ¼ĩ˜ЍŠĴʄ2̫ͩ ̂  cɮ̓Ĵǻċ:n̛үǺ˜ЍїѾ*ȁTn̛ȸ¼ĩ˜Ѝɮĭ$xhr ɟ˓ĴүǺ˜Ѝ þ̛ɽ˸ϽG ϵϝ˼їɮǻUͩ ʭn̛ xhr ɟ˓cΔćʄ2Àҷ̫ŹlưВþT̕ϵҷїϡR̫̀k̛ xhr :post, :create, relationship: { followed_id: other_user.id } ǻU̺»xhr ɟ˓̫ͩ ìɕɮ̷ư̫ HTTP ɟ˓ͩ9ìɕɮÌkĉͩìɕɮ  Hash˜‹΁ɮ ȸ¼ĩ ̫ params õҀ̫~ěTÀ̫˜Ѝ ʠǻUȏ̷–̫ɈkɎ‘ expect Ļ ʨʙɕҀɮɮňÊǼ §ƅ5 їʼ˜ЍЗɪ Ĵ͘Ʈ ǻUϬn̛Ĉ̫ͪ create ě destroy ÌkĞư Ajax ИˇїÌk*ÀþĞư̫ ɮɱѫ̫ POST Иˇě DELETE ИˇǻUϬ‚̫ɮ ǃȷ»ɱѫ̫ HTTP ИˇɩјϡҹҷтċìϮ 11.2.4 ωήǃȷ» Ajax Иˇɩn̛ JavaScript јϡŌ̕ȸ¼ĩ̫R̀ŠR̀ 11.38 ȁ͈Ĵ 11.5 ω̫Ό1 ǻ UKΑ5 ͑ɹͮÞ̫ų̓ɟƻ R̀ 11.38 Ĵ Relationships ȸ¼ĩ Ğư Ajax Иˇ app/controllers/relationships_controller.rb class RelationshipsController < ApplicationController before_action :signed_in_user def create @user = User.find(params[:relationship][:followed_id]) current_user.follow!(@user) respond_to do |format| format.html { redirect_to @user } format.js end end def destroy @user = Relationship.find(params[:id]).followed current_user.unfollow!(@user) respond_to do |format| format.html { redirect_to @user } format.js end end end R̀ 11.38 n̛5 respond_to ɟ˓ʢȰȷ»̫ИˇͶľјϡĈ̫ɈkїѾ̛»̫ respond_to ě RSpec ̫ respond_to ˎXhγ΀repond_to ɟ˓̫¢˓þιɽ˸ϽGўͼlϬ̾ѱŠ̫R̀ 441 respond_to do |format| format.html { redirect_to @user } format.js end üɽ ϡ_ϧȆϡqȰИˇ̫ͶľήŲ ĴŌ̕ Ajax ИˇɩRails _οÌЛ̛ɘVĉěÌkĉ ʠ̫“ďɽ JavaScript ̫ ERbJavaScript Embedded Ruby” ɘVȇƒĉ$ .js.erboŠ create.js.erb ě destroy.js.erblþιƝΒ̎»5ї͑ɘVɮþT Óď JavaScript ě Ruby R̫̀þT̛ʌŌ̕ǃÀҹҷ̫ŹĴ–˕̛Ȁěó˟–˕̛Ȁɩɹɞ̛ȀЬəҹҷ ̫ŹƊҲϬµƶї͑ɘV Ĵ JS-ERb ɘV Rails οÌȼp5 jQuery Ư̫ƣÍ®ɕþTѫѐ“ɘʄžПʬľDocument Object Model DOM”Ō̕ҹҷ̫ŹjQuery Ư ɽNjŐŌ̕ DOM ̫®ɕc̓ĴǻUü_̛»˜ ̫ӊǻUϬ ̾ѱѫѐ id ϓó DOM ‹΁̫Ψ‹ͨĂoŠϬϓó follow_form ‹΁ǻUþTn̛Š̫R̀ $("#follow_form") ìϮR̀ 11.23ї‹΁ɮÓďϥÞ̫ divήɮϥÞʄсҷ̫ú˓ě CSS ʠ# ͨĂϥ͈ CSS ̫ id̜ʶlþι̎»5jQuery ě CSS ʠ˸Ă . ϥ͈ CSS ̫ class ǻU_n̛̫ͩ9®ɕɮ htmlŮ_n̛ìɕ ȦŲ̫ŹyɌ‹΁ȁÓď̫ HTMLoŠŠʔϬȏɗϥ ÞȮǺŪͨ" "foobar"jQuery R̀þTї(¢ $("#follow_form").html("foobar") ěƤϰ̫ JavaScript ɘVĈJS-ERb ɘVіþTn̛Ɩ‘ƻ Ruby R̀Ĵ create.js.erb ɘV ǻU_ȏ– ˕̛ȀϥÞȮǺó˟–˕̛ȀϥÞǺɖ˕Ċƫɹɞ–˕έ̫ɕҀŠR̀ 11.39 ȁ͈їʼR̀ ̛»5 escape_javascript ɟ˓Ĵ JavaScript ¢‘ HTML R̀ǐҽn̛їɟ˓ž HTML јϡт) R̀ 11.39 µƶ–˕“–΀”̫ JS-ERb R̀ app/views/relationships/create.js.erb $("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>") $("#followers").html('<%= @user.followers.count %>') destroy.js.erb ɘV̫ŹͶbŠR̀ 11.40 ȁ͈ R̀ 11.40 ҉ʽ–˕“–΀”̫ JS-ERb R̀ app/views/relationships/destroy.js.erb $("#follow_form").html("<%= escape_javascript(render('users/follow')) %>") $("#followers").html('<%= @user.followers.count %>') ʑѝR̀ĊlưВЇҕ̛ȀЬəҹҷ̺ –˕Ǽó˟–˕̛ȀĊҹҷɮɮ̻̫ˎɽ½ɞŸӎЈ  ˜ЍɮčþTѫѐ $ bundle exec rspec spec/ 442 ͩ 11 ͥ –˕̛Ȁ Ĵ Rails n̛ Ajax þTЂ̫ŕŐ5ȎʅõÔ̫0ǕǻUüɮKΑ5˸̭˂ʄ2˜P̫Ź0ɮŠʶl þTȰʶ$Ń̈́ŭ1˜PɹӑΈ̛̫˓ 11.3 M©DĮ ȷʌǻUϬų͈̓o͘Ʈɼҭ̫Éι ÌǙ²ϥŃʄʄω̫Źͯɮ’2ɼӑˤ̫Ѹ¯5Űɗ̫ÌǙ²ϥ ɮT 10.3.3 ω̫#ɩÌǙ²ϥ$Ń̈́ų̫̓²ϥ Ҧ5ǃÀ̛ȀοƜ̫ǎà*ŏіÓď5Pȁ–˕̛Ȁ̫ǎ à$5ų̓їʠ̫ÉιǻU_̛» ANjӑΈ̫ RailsRuby ě SQL Ȏʅ ĭ$ǻUϬ‚̫8ǧNjŐĴʶ*Àɼş˧ʪǻUϬų̫̓ɮH(ʠ̫Éιij 11.5 ɯ͈5ɼΐϬų̫̓ÌǙ² ϥij 11.8 іɮĈ Ʀij 11.3.1 üûhċù ǻUžÌǙ²ϥ̫ʐǜɮNjͮÞ̫ij 11.19 ɯ͈5 ͈o̫ microposts ϥěϬɯ͈̫ÌǙÌǙ²ϥƊɮ ϬȏǃÀ̛Ȁȁ–˕̛Ȁ̫ǎà0ÓȠǃÀ̛ȀοƜ̫ǎàM microposts ϥ ó¬ʌŠij ͱŘȁȦ ij 11.18 ɯ͈ɽÌǙ²ϥ̛̫ȀЬəҹҷʐǜij 443 ĭ$ҲϬȏȦŲ̛Ȁȁ–˕̛Ȁ̫’Ѹǎàó¬ʌǻUϹ±Ų) ĉ$ from_users_followed_by ɟ˓ Tҷ̫ɟƻЛ̛ Micropost.from_users_followed_by(user) ϝ˼ǻUі̾ѱǚ(Ų)їɟ˓cĴʶ*ÀæþTΠ¢˜Ѝʨ˜Ů̫ÉιɮčȧІǯų̓5˜Ѝ̫–Ҏ ɮϬϭ̱͑ǧ¥ ÌǙ²ϥ ϬÓďϧ–˕̛Ȁě̛ȀοƜ̫ǎàήιÓďʂϧ–˕̛Ȁ̫ǎàÀҷ̫ ˜ЍƝΒʨ˜5˜ ͑ǧ¥ R̀ 10.35 ӎЈ5ÌǙ²ϥ ɽ̛ȀοƜ̫ǎàήˎɽʂϧ–˕̛Ȁ̫ǎà ɤ˼ǻUƝΒų̓5–˕̛ȀÉιѶƊʑžͩ͑ǧ¥̫˜ЍĎʨ˜ÌǙ²ϥ ɮčÓď5ϧ–˕̛Ȁ̫ǎ àŠR̀ 11.41 ȁ͈ ij 11.19 id $ 1 ̛̫Ȁ–˕5 id $ 27810 ̛̫ȀĊnj»̫ÌǙ²ϥ R̀ 11.41 ҂žÌǙ²ϥ˜Ѝ̫ɼΐ̂ spec/models/user_spec.rb require 'spec_helper' describe User do . . . describe "micropost associations" do before { @user.save } let!(:older_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago) end let!(:newer_micropost) do FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago) end . . . describe "status" do let(:unfollowed_post) do FactoryGirl.create(:micropost, user: FactoryGirl.create(:user)) end let(:followed_user) { FactoryGirl.create(:user) } 444 ͩ 11 ͥ –˕̛Ȁ before do @user.follow!(followed_user) 3.times { followed_user.microposts.create!(content: "Lorem ipsum") } end its(:feed) { should include(newer_micropost) } its(:feed) { should include(older_micropost) } its(:feed) { should_not include(unfollowed_post) } its(:feed) do followed_user.microposts.each do |micropost| should include(micropost) end end end end . . . end ǻUϬȏÌǙ²ϥ̫ų̓BΖ Micropost.from_users_followed_by ɟ˓ŠR̀ 11.42 ȁ͈ R̀ 11.42 Ĵ User ʬľ ʑų̓ÌǙ²ϥ̫ɟ˓ app/models/user.rb class User < ActiveRecord::Base . . . def feed Micropost.from_users_followed_by(self) end . . . end 11.3.2 Fã‡óM©DĮ ̓ĴǻUϬʌŲ) Micropost.from_users_followed_by ɟ˓5$5ϡɘͮ˖ĴĊҷ̫Ź ǻ_n̛ “ÌǙ²ϥ”ȦRїɟ˓ĭ$Ϭų̫̓Δʔɽ˸ŎʇĭʶǻU_ ˸ ˸̫ЗɪÌǙ²ϥ̫ų̓ѐ͘ ӊǻUϬ̾ѱҲϬn̛ǚʠ̫ʙБДúǻUϬ‚̫ɮM microposts ϥ ó¬ϧ–˕̛Ȁòƞ̫ǎà 0Ϭó¬̛ȀοƜ̫ǎàžʶǻUþTn̛Ͷbҷ̫ʙБДú 445 SELECT * FROM microposts WHERE user_id IN () OR user_id = ¢їʙБДúɩǻU€І SQL Ɋȥn̛ IN –ҎŪʨ˜үćɮčÓďȦŲ̫‹΁іşSQL Ɋȥ Ĵ 10.3.3 ωų̓#ɩÌǙ²ϥɩɮЛ̛ Active Record ̫ where ɟ˓ŰǺҷї͑ʙБ̫ŠR̀ 10.36 ȁ ͈їʼR̀ ̛»̫ʙБNjͮÞüɮѫѐǃÀ̛Ȁ̫ id ó¬5Pòƞ̫ǎà Micropost.where("user_id = ?", id) ή̓ĴǻUѯ»̫ǧ¥Ŏʇ̫ŐϬn̛Ͷbҷ̫R̀ų̓ where("user_id in (?) OR user_id = ?", following_ids, user) ĴȦŲʙБʋVɩǻUn̛5 Rails ̫·Ų̛ user Rɻ user.idRails _οÌϓớȀ̫ idǻUі ̹̣5ɟ˓̫Л̛έ Micropostĭ$ǻUü_Ĵ Micropost ʬľ n̛їɟ˓ Mҷ̫ʙБʋVþT̺¬ǻUҲϬ̚Ǻ ɕ΍˜‹΁$ϧ–˕̛Ȁ̫ id̚Ǻїɕ΍̫ɟ˓* ɮn ̛ Ruby ̫ map ɟ˓їɟ˓þTĴXDZ̫“þʓ&enumerable”žПЛ̛oŠÓď5‹΁̫үćͶž Пɕ΍Hash ͪ11ǻUĴ 4.3.2 ω &oKΑѐїɟ˓˜̛˓Š $ rails console >> [1, 2, 3, 4].map { |i| i.to_s } => ["1", "2", "3", "4"] ˆҷї͑Ĵʿ‹΁Л̛Ĉ ɟ˓̫ǧ¥ɮNjƤϮ̫ȁT Ruby $ʶŲ)5 ͑ͮ¢DžƻĴ & ͨĂĊҷ кϧЛ̛ɟ˓̫ Symbol Džƻ 12 >> [1, 2, 3, 4].map(&:to_s) => ["1", "2", "3", "4"] ˼ĊŸЛ̛ join ɟ˓ìϮ 4.3.1 ωƊþTƃɕ΍ ̫‹΁ćƫгʌ΍ǺŪͨ"Ƌ΁*Җ̛ѪĂÊ ͝ ʣ¯Ʒ >> [1, 2, 3, 4].map(&:to_s).join(', ') => "1, 2, 3, 4" ì˽ҷKΑ̫ɟ˓ǻUþTĴ user.followed_users ̫ʿ‹΁Л̛ id ɟ˓nj» ̜ϧ–˕̛Ȁ ̫ id ΍Ǻ̫ɕ΍oŠžɕȰƯ ͩ 1 ̛ȀήϷƊþT̛ҷ̫R̀ų̓ >> User.first.followed_users.map(&:id) => [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 11. þʓ&̫žПɼŃʄ̫Ϭˇɮǐҽų̓ each ɟ˓̛ʌѰèүć 12. їͮ¢ɟƻɼ¶ɮ Rails ž Ruby ̫ȇƒĭ$Njɽ̛ȁT Ruby ɼĊοƜ0ų̓5Nj̃Ď 446 ͩ 11 ͥ –˕̛Ȁ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51] ˜ųĭ$ї̛͑˓ŕɱѰ5ȁT Active Record әϻƝΒȼp5 >> User.first.followed_user_ids => [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51] ѝR̀ ̫ followed_user_ids ɟ˓ɮ Active Record ʢȰ has_many :followed_users –γìϮR̀ 11.10ćǺ̫їʠǻUüҲĴ–γĉ̫ĊҷÊ _ids ƊþTϓó user.followed_users үć ȁɽ̛Ȁ̫ id 5̛Ȁ id ΍Ǻ̫Ūͨ"Š >> User.first.followed_user_ids.join(', ') => "4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51" ѐǃȽ‘ SQL Дú ɩlɣҽȂÌ̚ǺŪͨ"? Ƚ~Ɉk_$lRÐĈɩ0ѵ5 AɕȰƯ*Җ̫› ŹҕӄȁTǻUųҠϬn̛̫üɮ user.followed_user_ids ήƝ ̓ĴїҜʼlþιƝΒǯ»5Ϭn̛ Micropost.from_users_followed_by(user)ƊϬĴ Micropost Ͷ Ų) Ͷɟ˓4.4.1 ωͮÞ̫KΑѐїͶɟ˓̫¶ʷŲ)ŠR̀ 11.43 ȁ͈˜ 5ѝ¯ʑnj»̫ AR̀ Óď R̀ 11.43 from_users_followed_by ɟ˓̫¶ʷŲ) app/models/micropost.rb class Micropost < ActiveRecord::Base . . . def self.from_users_followed_by(user) followed_user_ids = user.followed_user_ids where("user_id IN (?) OR user_id = ?", followed_user_ids, user) end end ϝ˼R̀ 11.43 *À̫ϼЅѹɮT€І$Ń̈́јϡ̫cnj»̫R̀æɮþ̛̫lþTѓϡ˜ЍӎЈ ưВ ɮþTѫѐ̫ $ bundle exec rspec spec/ ĴʗA͘Ʈ їʠ̫¶ʷų̓ƝΒι˯зœѸ¯Ҳˇ5ѐїɮǻUɼΐϬn̛̫ų̓ɟƻĴΚΛҘЙ Ƅω*ÀlþTǯ $H(ȼ͈ Šʔ̛Ȁ–˕5 5000 ̛ȀĖ  447 11.3.3 €ÚŁsubselect Š Ƅωʃƍ ȁЗ̫11.3.2 ω̫ų̓ɟƻǃÌǙ²ϥ ̫ǎàɕҀNjŐɩǝιƊ_ңї͑ǧ¥þι_ ò̚Ĵ̛Ȁ–˕5 5000 ̛ȀĊʄƄωǻU_ѿɞų̓ÌǙ²ϥĴ–˕̛ȀɕҀNjŐɩǝιϥ̓0_Nj ş 11.3.2 ω ȁ̛R̫̀ҕӄĴ:followed_user_ids = user.followed_user_ids їϡR̀Ů_ȏȁɽϧ –˕̛Ȁ̫ id ó¬ū‘ū˼ĊŸµƶ ‹΁ɕҀěϧ–˕̛ȀɕҀ̷Ĉ̫ɕ΍ɤ˼R̀ 11.43 ̴̫̫üɮ $5ʨʙүćɮčÓď5ȦŲ̫‹΁Ѷ(Ɗ ŲūĴ ͑ɹӑɐ̫ɟ˓˜ų SQL ̻̫ȼp5҂žї͑ҕӄ̫^ ÔȺɠ n̛ũʙБȏʙБϧ–˕̛Ȁ id ̫ɈkɎ‘ɕȰƯƏјϡ ҂žÌǙ²ϥ̫ѿʐMR̀ 11.44 ̫ƄɌÌƷţ R̀ 11.44 Ɍј from_users_followed_by ɟ˓ app/models/micropost.rb class Micropost < ActiveRecord::Base . . . # Returns microposts from the users being followed by the given user. def self.from_users_followed_by(user) followed_user_ids = user.followed_user_ids where("user_id IN (:followed_user_ids) OR user_id = :user_id", followed_user_ids: followed_user_ids, user_id: user) end end $5Ζ ʷ‚¦ōǻUȏ where("user_id IN (?) OR user_id = ?", followed_user_ids, user) ȮǺ5ͪɐ̫ where("user_id IN (:followed_user_ids) OR user_id = :user_id", followed_user_ids: followed_user_ids, user_id: user)) n̛ҕÂȽ~ϝ˼þTcǃǻUϬĴŐŌȽ‘Ĉ ~ɩĊ ͑¢˓ƊɟtŐ5 ҷїʼЏϥɪǻUϬĴ SQL ʙБДú ʭ̛» user_idͮÞʌЗƊɮǻUϬȏҷїϡ Ruby R̀ followed_user_ids = user.followed_user_ids ȮǺÓď SQL Дú̫R̀ followed_user_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id" 448 ͩ 11 ͥ –˕̛Ȁ ҷїϡR̀n̛5 SQL ̫ũʙБДúѶ(҂ž id $ 1 ̛̫ȀɗʙБДúƊþT¢Ǻ SELECT * FROM microposts WHERE user_id IN (SELECT followed_id FROM relationships WHERE follower_id = 1) OR user_id = 1 n̛ũʙБĊȁɽ̫үćÓď–΀ѹ_B̜ɕȰƯŌ̕їʠǝιƊnj»ȼÛ513 ɽ5їAŃ̈́ǻUƊþT̽Ȃų̓ɹӑɐ̫ÌǙ²ϥ5ŠR̀ 11.45 ȁ͈˕DZĭ$̓ĴϬn̛Ή SQL Д úȁT followed_user_ids ɮϧȽ~јДú ̫ήˎɽѫѐт)̫ɟƻ˜ų͑ɟƻѹþTn̛ü ѐї͑ǧ¥n̛Ƚ~Ɉkɹć̕ R̀ 11.45 from_users_followed_by ɟ˓̫ɼΐ̂ʄ app/models/micropost.rb class Micropost < ActiveRecord::Base belongs_to :user default_scope -> { order('created_at DESC') } validates :content, presence: true, length: { maximum: 140 } validates :user_id, presence: true # Returns microposts from the users being followed by the given user. def self.from_users_followed_by(user) followed_user_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id" where("user_id IN (#{followed_user_ids}) OR user_id = :user_id", user_id: user.id) end end їʼR̀Δć5 RailsRuby ě SQL ̫^Ñэ»5̴̫ή‚̫Njşǃ˼ũʙБ0ɮι̫ž:ɹ œľ̫ΤͤήϷþιϬn̛“Ċÿkbackground job”Ƹʷ̚ǺÌǙ²ϥǝι^ÔїЏӄƝΒд¬5ʄ2 ̫ώİ 11.3.4 ËûM©DĮ ΠŰR̀ 11.45ÌǙ²ϥÉιƊų̓5ȼѻ home ÌkȁҲ̫R̀ŠR̀ 11.46 ȁ͈їʼR̀̚Ǻ5 þ¯ҹɯ͈̫ÌǙ²ϥõҀþĴϱij n̛Šij 11.20 ȁ͈14˕DZpaginate ɼΐ_Л̛R̀ 11.45 Ų )̫Ͷɟ˓ ʭüMɕȰƯ ó¬ 30 ͳǎàŠʔlǯӎЈ þTʙ̺“ƷòɿËĩ”̫ɥǒ R̀ 11.46 Ų)5þ¯ҹÌǙ²ϥ̫ home Ìk app/controllers/static_pages_controller.rb 13. µƶũʙБДúɹŐӑΈ̫ɟƻИҘЙHacking a subselect in ActiveRecord ɘ 14. $5ij 11.20 ɯ͈̫ÌǙ²ϥɹş̺ǻοƜÌȂĴ Rails ȸ¼ÿ ʑ5 Aǎà 449 class StaticPagesController < ApplicationController def home if signed_in? @micropost = current_user.microposts.build @feed_items = current_user.feed.paginate(page: params[:page]) end end . . . end 11.4 ŒĘ ų̓5ÌǙ²ϥĊʄ2̫ʡǏ͈o͘ƮƊƷòŰ5ї͘Ʈ˲͈5 Rails ’Ѹ̫%ϬÉιÓȠʬľϱij ȸ¼ĩʬʎƎѸϱijѐ˰ĩɕȰӎЈĬЛ®ɕhas_many/belongs_to ě has_many through – γů’˜ЍTîѸΧҦʶ*ŏRails іɽNjŐÉι~njǻUŭ1lþTȏʄωk$ĊΛŭ1̫ͩ ͤ ҷ©ƄωKΑ5þTž͈o͘Ʈјϡ̫Éιȇƒ0žĊΛŭ1ȼp AìάЬˬ ij 11.20 ɯ͈5ÌǙ²ϥ̫ӊҹ 450 ĴKΑþž͘Ʈјϡ̫Éιȇƒ*Àɼşȏʄ̫ͥɌÌćƫ»%¯Ɋ $ git add . $ git commit -m "Add user following" $ git checkout master $ git merge following-users ě*À ʠl0þTȏR̀ȹѡ» GitHubіþTѸΧ» Heroku $ git push $ git push heroku $ heroku pg:reset DATABASE $ heroku run rake db:migrate $ heroku run rake db:populate ͩ 11 ͥ –˕̛Ȁ 11.4.1 ²ā.ą›ûKħ ʄωƶϿ̫Éιȇƒ˶dzŃʄѹɮʌοƤϰ Web ͘Ʈ̫ υÉιŠź̀ȼѻě Email ĵĸ͆ϻǼɮʌοĈͶ ľ͘ƮoŠȿ΂ĬŎě͐xοƜų̓©ÉιȇƒþTϽlMɓ̫͘кŭέõǺο%͘ƮƷòέ ŠʔƷţɩϳnjɽ˸ҭ0̛ŚǞMұƷţų̓ Éι͆ųɽҭƴ$5ƣÍlǻþTȼ˸ƶІǝ̫ƶ Ͽͩ ˸ĴƷţų̓ɞÉι*À˝ϲ  RailsCasts ̫ǂʦ̺  Ryan ɮčKΑѐͶb̫Éι15ŠʔP KΑѐ̺ ̷–̫ϱӃ_ω̹NjŐɩҖͩ9˸ǟɮĴ Google œώİ̫ȿ΂lϬų̫̓ÉιſȌ̷– ̫àɘěɓ͘Web ͘ƮƷòɮɽҭƴ̫MɽΒӎ̫ƷòέѶѾóΒǟɮ_žlɽȁƣÍ̫ ҷ²¬̫ÉιNjŐѹɮɽ ŲȨǽǝ̫ĴÉι̫KΑ ǻ_Ζl Ų̫ȼ͈ĔЊlų̓ѐ͘ þι_̛»̫ Ƙ™ϝ˼ɽȼ͈cɮїAÉιų̓гʌˀͥĊ̫Ό1ҭŐ5Ĵˎ̻ÉŖ*ÀÚºхϷɎƹĭ$ɩҖɽ Ҥǻɣ˓ ž ̫шƀѐŠʔlžїAÉιdz—жƃʌǻþι_òƞ Ǎ̫͢ɘͥǼϱӃKΑ И »ʄ2̫Τͤ http://railstutorial.org/ ϺҘ Feed ϓóɼɞ̫ɹɞ ly Twitter ŠЄ̛Ȁn̛“@replies” ̫ʣƻјϡĬŎĬŎ0ɮ ͳǎàѐŹ̫ƷŘɮ @ ͨĂÊ̛ȀĉĬŎü _¬̓ĴϧĬƠ̆Ȁ̫ÌǙ²ϥěͷ̫ÌǙ²ϥ Иų̓ ͮÔ̫ĬŎÉιҤ¼ĬŎüþT¬̓Ĵȷɋέ ěòѡέ̫ÌǙ²ϥ ų̫̓ѐ͘þιϬĴ microposts ϥ ʑ in_reply_to ²іϬĴ Micropost ʬľ ˦Ê including_replies k̛Ł ĭ$ǻU̫͈o͘ƮˎɽҤ¼̛Ą̏DŽĉϬɮġ ̫ȁTlþιϬ¤Ų ϬѼ̛H(ɟƻϥ̛͈Ȁ̫сY ͑ɟƻɮΔć id ěĉŪoŠ @1-michael-hartlû ͑ɟƻɮĴ˕žϥÞ ˦Ê ̛ȀĉŪʼ̛Ȁ ĉƃɮġ ̫˼Ċ̛ʌϥ͈ @replies 15. ˕DZRailsCasts ΒƤ_̹̣˜Ѝþιɮ$5Ϭȸ¼ϱӃ̫ЧҀěґƴїþι_Ͻl_ҌDZϻ$˜ЍƫѿϬϯ̺ѐ RailsCasts ̷–̫ϱӃ̾ѱǚ(ƷòĊǻƶϿlȧ˽“˜ЍӌÌƷò”ê³ų̓ÉιǻƶϿl̺  RailsCasts ̫How I testl_̺» Ryan Bates ĴųҠ̫Ʒò ΒƤ_n̛ TDDήP̫˜Ѝӈʣěʄ2̫Njˆ 451 Ă1 Twitter ɊȥĴǎà̫ÀҷÊŪʾ“d”òѡ͐xИĴ͈o͘Ʈ ʑїÉιų̫̓ѐ͘ þιϬµƶ Message ʬľіϬn̛ʵ³ϥэƻÖѺǎà̫Ź į:徊 Иų̓ǃ̛Ȁɽɞͷɩċϧ–˕̛ȀòѡȼѻѷV̫Éιƫȏї ÉιІ$þѥ̫їʠŠʔ̛Ȁǯȷɋȼ ѻƊþTѥȟїÉιų̓їÉιҲϬŭ1ŠhĴ Rails òѡѷVǻƶϿϯ̺ RailsCasts ̫Action Mailer in Rails 3 үʌŭ1 ‰ÿ¾Š ̓ĴŠʔ͘Ʈ̛̫ȀǓЁź̀5ƊˎÈ˓ϓó5ĭ$ǻUĴͩ 6 ͥn̛5Þċź̀Êź͘ƮˎÈ˓ȏź̀ ѫѐ Email òѡΖ̛ȀcɮǻUþTòѡ ѿІź̀ϥÞ̫҈ȷȧ˽ RailsCasts ̫Remember Me & Reset Password үʌyʵїҕӄ å>Āĸ Ҧ5ÖѺ Email ĵĸ̫ʵ³ϥэƻ*ŏ͈o͘Ʈ̓Ĵˎɽ˜Pɟ˓þTӎЈ̛Ȁ̫ Email ĵĸɮčć˓ИĴ˕ žʷӏ ˦Ê͆ϻ̛Ȁ˕žї ʷїÉιưВĴ˕žɩơ̑ȀІ$ʂ˴˘̉Ǚòѡ ƁÓď˴˘҈ȷ̫ѷ Vǃ҈ȷϧ˸­ĊŸơ̑ȀІ$Ɲ˴˘̉ǙlþιϬҘЙ Rails state machine ̷–̫ɘͥŭ1ŠhĴʂ˴˘ ě˴˘̉Ǚ*ҖтȮ RSS Feed И$ʿ ̛Ȁ̫ǎàɹɞµƶ  RSS˼ĊŸ$̛Ȁ̫̉Ǚ²ϥų̓  RSSŠʔþTlіþTn̛сY ӎЈʆ¼Ҥ¼žÌǙ²ϥ RSS ̫ЇҕRailsCasts ̫Generating RSS Feeds үþTΖl AƣÍ REST API NjŐΤͤѹȼp5“ư̛Π͘ȷøApplication Programmer InterfaceAPI”ŠЄͩɟ͘Ʈϓógetµƶ postɹɞputě·Ҧdelete͘Ʈ̫ЬˬИ$͈o͘Ʈų̓ї͑ REST APIų̫̓ѐ͘ þιϬ$͘ Ʈ̫Őɕȸ¼ĩÌk˦Ê respond_to R̀ĻìϮ 11.2.5 ωĞư XML Ͷľ̫ИˇИ˕DZů’ҕӄAPI ưВüžȲʈ̛̫ȀƷɎ ¿Ē ̓ĴҦ5˝ϲ̛Ȁ΂ƼҹҷǼέʙ̺˜P̛Ȁ̫ÌǙ²ϥ*ŏˎɽÈ˓Ȍ»ûơ̫̆ȀИų̓ȿ΂Éιʌ ƾϤїΣҨ˼ĊŸ˦Êȿ΂ǎà̫ÉιRailsCasts ̫Simple Search Form үþTΖl AƣÍŠʔ l̫͘ƮѸΧĴ•D%ʆǼ̛ɿËĩǻƶϿln̛ Thinking Sphinxìά RailsCasts ̫Thinking Sphinx үŠʔl̫͘ƮѸΧĴ Heroku lưВì˽Full Text Search Options on Heroku ɘ ̫Зɪ 452 ͩ 11 ͥ –˕̛Ȁ 11.4.2 cĜƒûʼnì ĢƲěΤѹɽNjŐ Rails ЬˬήŐnj_ϽlȨϊ̼þħ̫ɮlҘЙ»їѾɩƝΒþTŭ1©+ȁɽ̫ ˜P̾Љ5ҷɮƶϿlĊΛŭ1̫Ьˬ • ʄ2ѺŝϱӃ ǻ$ʄ2DŽ¼5ŹŒз̫ѺŝϱӃҦ5ϭ̱ʄ2̫Ź*ŏĴϱӃ ǻіKΑ5Nj ŐƄȎƚǃ˼ϱӃіιƾϤã½2̫зϽlϯ̺ºGɮŠhƷò̫lþTĴʄ2̫ΤͤШ3ї AϱӃ • RailsCasts ŠhǁЛ RailsCasts ̫ѿϬǝѹ$ѐǻƶϿl˝ϲ  RailsCasts ̫ϱӃǂʦϯ̺ldz —ж̫ϱӃ • Ruby ě Rails ̷–̫2 ŭ1 Ruby ǻȹϐ Peter Cooper ̫Ruby ‘ҒDavid A. Black ̫The WellGrounded RubyistRuss Olsen ̫Eloquent Rubyě Hal Fulton ̫Ruby *ѱΚΛŭ1 Rails ǻȹ ϐ Obie Fernandez ̫Rails 3 *ѱě Ryan BiggYehuda Katz ćϖ̫Rails 3 ųǽИҘЙͩ 2 ̂ • PeepCode ě Code School PeepCode ̫ϱӃɓ͘ě Code School ̫B=ɓ͘ЧҀѹNjӑǻ̻Ǐĵċlȹ ϐ 11.5 Ė 1. ˦Ê҂ž҉ʽȦŲ̛Ȁ–˕–γѫѐR̀ 11.4 ěR̀ 11.16 ̫ dependent :destroy ų̫̓˜ Ѝȼ͈ þì˽R̀ 10.12 2. R̀ 11.38 ̛»̫ respond_to ɟ˓þTȼó¬ʌɎ‘ Relationships ȸ¼ĩ ή respond_to R ̀ĻþTn̛ Rails ̫ respond_with ɟ˓RɻИѓϡ˜Ѝ΍V͆ϻҷɈkųɠĊnj»̫R̀ ŠR̀ 11.47 ȁ͈Lɮʵ̫͆respond_with ɟ˓̫ГΎ̛˓ИĴ Google ȿ΂“rails respond_with” 3. ѿʐR̀ 11.31ȏ–˕έ²ϥҹҷͷ²ϥҹҷӊҹě̛ȀЬəҹҷ̫ѫ̛Ѹ¯ȼó¬ʌµƶǺ ƎѸϱij 4. ȧ˽R̀ 11.19 ̫ɟƻΠ¢˜Ѝʨ˜GЬəҹҷ̫–˕ɕҀΙϹ R̀ 11.47 ѿʐȏR̀ 11.38 õnjɹͮ˖ class RelationshipsController < ApplicationController before_action :signed_in_user respond_to :html, :js def create @user = User.find(params[:relationship][:followed_id]) current_user.follow!(@user) respond_with @user end 453 def destroy @user = Relationship.find(params[:id]).followed current_user.unfollow!(@user) respond_with @user end end 454

    Top_arrow
    回到顶部
    EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高进,我们会尽快处理。