over 2 years ago

重點1:怎麼使用application_helper.rb,在application_helper.rb弄的method,可以用到view裡面去。
重點2:這個的用法也很重要:<% provide(:title, "Home") %>
參考:method / block / yield / Proc / lambda 全面解釋
參考:yield and provide() inside template

provide是放在<% %>,所以不會顯示出來。
provide stores a block of markup in an identifier for later use. In this case, 'Help' in the symbol :title. The provide is enclosed in <% %> to indicate it is executing this code and not printing out in the view.
yield是放在<%= %>,所以會顯示出來。
yield in this case just spits that block back out. The yield is enclosed in <%= %> to indicate it is being printed out into the view.
Think of it as setting a variable and printing out a variable.
See: content_for 和provide for more information. Note that provide is really a wrapper for content_for so that's where the good stuff is in that link.

重點3:ifunless 分不清楚

  1. This uses the built-in Rails function stylesheet_link_tag (which you can read more about at the Rails API) to include application.css for all media types (including computer screens and printers).
    stylesheet_link_tag 後面的application指的是application.css

    app/views/layouts/application.html.erb
     <!DOCTYPE html>
    <html>
    <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
    <%= stylesheet_link_tag    'application', media: 'all',
                                              'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
    </head>
    <body>
    <%= yield %>
    </body>
    </html>
    
    <%= stylesheet_link_tag 'application', media: 'all',
                                       'data-turbolinks-track' => true %>
    
  2. 一步一步的做調整:(這邊的重點應該是在於怎麼使用application_helper.rb,在application_helper.rb弄的method,可以用到view裡面去。)

    <%= yield(:title) %> | Ruby on Rails Tutorial Sample App
    

    這兩個會相呼應。

    <% provide(:title, "Home") %>
    <h1>Sample App</h1>
    <p>
    This is the home page for the
    <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
    sample application.
    </p>
    

    在application_helper.rb裡面,寫一個新的method。
    we’ll define a custom helper called full_title. The full_title helper returns a base title, “Ruby on Rails Tutorial Sample App”, if no page title is defined, and adds a vertical bar preceded by the page title if one is defined (Listing 4.2).1

    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
                page_title + " | " + base_title
            end
        end
    end
    
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
    

    上面就可以改成下面這樣:

    <title><%= full_title(yield(:title)) %></title>
    

    然後把它加到application.html.erb裡面去

    app/views/layouts/application.html.erb
     <!DOCTYPE html>
    <html>
    <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= stylesheet_link_tag    'application', media: 'all',
                                              'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
    </head>
    <body>
    <%= yield %>
    </body>
    </html>
    

    接著要把home.html.erb裡面的<% provide(:title, "Home") %>拿掉????

    app/views/static_pages/home.html.erb
     <% provide(:title, "Home") %>
    <h1>Sample App</h1>
    <p>
    This is the home page for the
    <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
    sample application.
    </p>
    

    這邊有點怪怪的,好像把<% provide(:title, "Home") %>拿掉,只是為了要測試能不能出現base_title = "Ruby on Rails Tutorial Sample App",如果真的上線,應該還是要把<% provide(:title, "Home") %>留著。

    app/views/static_pages/home.html.erb
     <h1>Sample App</h1>
    <p>
    This is the home page for the
    <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
    sample application.
    </p>
    
  3. 作者覺得 interpolation的方法比較好

    Concatenation, with a space in between
    first_name + " " + last_name 
    => "Michael Hartl"
    
    The equivalent interpolation
    >> "#{first_name} #{last_name}"
    => "Michael Hartl"
    
  4. put會多一行,print不會。print加上\n就會有跟puts一樣的多一行的效果。

    >> puts "foo"     # put string
    
    foo
    => nil
    >> print "foo"    # print string (same as puts, but without the newline)
    
    foo=> nil
    >> print "foo\n"  # Same as puts "foo"
    
    foo
    => nil
    
  5. Single-quoted strings don't allow interpolation,所以要用雙引號比較好""

    '#{foo} bar'     
    => "\#{foo} bar"
    
  6. Single-quoted strings:這邊看不懂

    >> 'foo'          # A single-quoted string
    
    => "foo"
    >> 'foo' + 'bar'
    => "foobar"
    
    >> '#{foo} bar'     # Single-quoted strings don't allow interpolation
    
    => "\#{foo} bar"
    
    >> '\n'       # A literal 'backslash n' combination
    
    => "\\n"
    
    >> 'Newlines (\n) and tabs (\t) both use the backslash character \.'
    => "Newlines (\\n) and tabs (\\t) both use the backslash character \\."
    
  7. 問號(?)是用在測試boolean: true or false的,對於流程控制特別有用。
    Note the question mark at the end of the empty? method. This is a Ruby convention indicating that the return value is boolean: true or false. Booleans are especially useful for control flow else + if

  8. 超過一個子句,就可以用 elsif (else + if)

    >> if s.nil?
    >>   "The variable is nil"
    >> elsif s.empty?
    >>   "The string is empty"
    >> elsif s.include?("foo")
    >>   "The string includes 'foo'"
    >> end
    => "The string includes 'foo'"
    
  9. to_s method that can convert virtually any object to a string

    >> nil.empty?
    NoMethodError: undefined method `empty?' for nil:NilClass
    >> nil.to_s.empty?      # Message chaining
    => true
    
  10. The code also shows an alternate use of the if keyword: Ruby allows you to write a statement that is evaluated only if the statement following if is true. There’s a complementary unless keyword that works the same way:

    puts "x is not empty" if !x.empty?
    
    >> string = "foobar"
    >> puts "The string '#{string}' is nonempty." unless string.empty?
    The string 'foobar' is nonempty.
    => nil
    
  11. It’s worth noting that the nil object is special, in that it is the only Ruby object that is false in a boolean context, apart from false itself. We can see this using !! (read “bang bang”), which negates an object twice, thereby coercing it to its boolean value:

    >> !!nil
    => false
    

    In particular, all other Ruby objects are true, even 0:

    >> !!0
    => true
    
  12. module ApplicationHelper: modules give us a way to package together related methods, which can then be mixed in to Ruby classes using include. When writing ordinary Ruby, you often write modules and include them explicitly yourself, but in the case of a helper module Rails handles the inclusion for us. The result is that the full_title method is automagically available in all our views.

    include module
    
  13. Arrays and ranges
    Array裡面的東西是有順序的,Hash裡面的東西沒有順序
    An array is just a list of elements in a particular order.

  14. split method:可以把string變成array

    >>  "foo bar     baz".split     # Split a string into a three-element array.
    
    => ["foo", "bar", "baz"]
    

    split('x'):按照()裡面的東西去拆分string,然後變成array

    >> "fooxbarxbazx".split('x')
    => ["foo", "bar", "baz"]
    
  15. Array 第一個元素的index是0,最後一個是-1:

    >> a = [42, 8, 17]
    => [42, 8, 17]
    >> a[0]               # Ruby uses square brackets for array access.
    
    => 42
    >> a[1]
    => 8
    >> a[2]
    => 17
    >> a[-1]              # Indices can even be negative!
    
    => 17
    
    >> a                  # Just a reminder of what 'a' is
    
    => [42, 8, 17]
    >> a.first
    => 42
    >> a.second
    => 8
    >> a.last
    => 17
    >> a.last == a[-1]    # Comparison using ==
    
    => true
    
  16. ==等於 , !=(“not equal”)不等於

    >> x = a.length       # Like strings, arrays respond to the 'length' method.
    
    => 3
    >> x == 3
    => true
    >> x == 1
    => false
    >> x != 1
    => true
    >> x >= 1
    => true
    >> x < 1
    => false
    
  17. emptyincludesortreverseshuffle:

    >> a
    => [42, 8, 17]
    >> a.empty?
    => false
    >> a.include?(42)
    => true
    >> a.sort
    => [8, 17, 42]
    >> a.reverse
    => [17, 8, 42]
    >> a.shuffle
    => [17, 42, 8]
    >> a
    => [42, 8, 17]
    
  18. 驚嘆號(!)可以把array的改變儲存起來:

    >> a
    => [42, 8, 17]
    >> a.sort!
    => [8, 17, 42]
    >> a
    => [8, 17, 42]
    
  19. push method<<:都可以把新東西加到array裡面去
    push method or its equivalent operator, <<

    >> a.push(6)                  # Pushing 6 onto an array
    
    => [42, 8, 17, 6]
    >> a << 7                     # Pushing 7 onto an array
    
    => [42, 8, 17, 6, 7]
    >> a << "foo" << "bar"        # Chaining array pushes
    
    => [42, 8, 17, 6, 7, "foo", "bar"]
    
  20. Ruby可以把integers 和 strings 合在一起:join
    join method 把array裡面的東西合成一個string:

    >> a
    => [42, 8, 17, 6, 7, "foo", "bar"]
    >> a.join                       # Join on nothing.
    
    => "4281767foobar"
    >> a.join(', ')                 # Join on comma-space.
    
    => "42, 8, 17, 6, 7, foo, bar"
    
  21. Range如果要改成array(to_a),要記得先用括號把range括起來:

    >> 0..9
    => 0..9
    >> 0..9.to_a              # Oops, call to_a on 9.
    
    NoMethodError: undefined method `to_a' for 9:Fixnum
    >> (0..9).to_a            # Use parentheses to call to_a on the range.
    => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
  22. Range來把array裡面的東西叫出來:
    %w是用來建一個文字array的:

    >> a = %w[foo bar baz quux]         # Use %w to make a string array.
    
    => ["foo", "bar", "baz", "quux"]
    >> a[0..2]
    => ["foo", "bar", "baz"]
    
  23. 不用特別去數array內有幾個元素,直接用index -1 就可以從頭掃到尾:

    >> a = (0..9).to_a
    => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >> a[2..(a.length-1)]               # Explicitly use the array's length.
    
    => [2, 3, 4, 5, 6, 7, 8, 9]
    >> a[2..-1]                         # Use the index -1 trick.
    
    => [2, 3, 4, 5, 6, 7, 8, 9]
    
  24. Range也可以用在文字上

    >> ('a'..'e').to_a
    => ["a", "b", "c", "d", "e"]
    
  25. 開始講BLOCK: ArrayRange的一些method都可以用block
    Both arrays and ranges respond to a host of methods that accept blocks
    譬如range (1..5)可以用 block { |i| puts 2 * i }

    >> (1..5).each { |i| puts 2 * i }
    2
    4
    6
    8
    10
    => 1..5
    
  26. block { |i| puts 2 * i }相等於下面這個:

    >> (1..5).each do |i|
    ?>   puts 2 * i
    >> end
    2
    4
    6
    8
    10
    => 1..5
    
  27. using curly braces only for short one-line blocks
    the do..end syntax for longer one-liners and for multi-line blocks:

    >> (1..5).each do |number|
    ?>   puts 2 * number
    >>   puts '--'
    >> end
    2
    --
    4
    --
    6
    --
    8
    --
    10
    --
    => 1..5
    
  28. 更多範例

    >> 3.times { puts "Betelgeuse!" }   # 3.times takes a block with no variables.
    
    "Betelgeuse!"
    "Betelgeuse!"
    "Betelgeuse!"
    => 3
    
    >> (1..5).map { |i| i**2 }          # The ** notation is for 'power'.
    
    => [1, 4, 9, 16, 25]
    
  29. %w是把array裡面的東西轉成string

    >> %w[a b c]                        # Recall that %w makes string arrays.
    
    => ["a", "b", "c"]
    
  30. map method returns the result of applying the given block to each element in the array or range.
    參考:map可以來產生出一個array: 常見 block 說明和應用:do, map, collect

    >> %w[a b c].map { |char| char.upcase }
    => ["A", "B", "C"]
    
    >> %w[A B C].map { |char| char.downcase }
    => ["a", "b", "c"]
    

    &:是個縮寫。 we’ll discuss in Section 4.3.3.

    >> %w[A B C].map { |char| char.downcase }
    => ["a", "b", "c"]
    >> %w[A B C].map(&:downcase)
    => ["a", "b", "c"]
    
  31. 這個其實也是block:

    test "should get home" do
    get :home
    assert_response :success
    assert_select "title", "Ruby on Rails Tutorial Sample App"
    end
    
  32. 之前的例子

    ('a'..'z').to_a.shuffle[0..7].join
    >> ('a'..'z').to_a                     # An alphabet array
    
    => ["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             # Shuffle it.
    
    => ["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]       # Pull out the first eight elements.
    
    => ["f", "w", "i", "a", "h", "p", "c", "x"]
    >> ('a'..'z').to_a.shuffle[0..7].join  # Join them together to make one string.
    
    => "mznpybuj"
    
  33. Hash沒有順序,只有keyvalue。如果需要有順序上的差別,記得用array:

    >> user = {}                          # {} is an empty hash.
    
    => {}
    >> user["first_name"] = "Michael"     # Key "first_name", value "Michael"
    
    => "Michael"
    >> user["last_name"] = "Hartl"        # Key "last_name", value "Hartl"
    
    => "Hartl"
    >> user["first_name"]                 # Element access is like arrays.
    
    => "Michael"
    >> user                               # A literal representation of the hash
    
    => {"last_name"=>"Hartl", "first_name"=>"Michael"}
    
  34. 舊的用法:=> called a “hashrocket”:

    >> user = { "first_name" => "Michael", "last_name" => "Hartl" }
    => {"last_name"=>"Hartl", "first_name"=>"Michael"}
    
  35. 用symbol比用string當key好。

    >> "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
    
  36. Symbols不能有-,也不能用數字作為開頭。

    >> :foo-bar
    NameError: undefined local variable or method `bar' for main:Object
    >> :2foo
    SyntaxError
    
  37. hash裡面沒有的key,會回傳nil

    >> user = { :name => "Michael Hartl", :email => "michael@example.com" }
    => {:name=>"Michael Hartl", :email=>"michael@example.com"}
    >> user[:name]              # Access the value corresponding to :name.
    
    => "Michael Hartl"
    >> user[:password]          # Access the value of an undefined key.
    
    => nil
    
  38. :取代=>,這樣跟javascript比較相似

    >> 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
    
    { name: "Michael Hartl", email: "michael@example.com" }
    
    { :name => "Michael Hartl" }
    

    這兩個其實是一樣的

    { name: "Michael Hartl" }
    
  39. hashes-of-hashes / Nested hashes:Hash裡面還有Hash

    >> params = {}        # Define a hash called 'params' (short for 'parameters').
    
    => {}
    >> 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"
    
  40. Hash也可以用each,不過hash會去抓a key and a value

    >> flash = { success: "It worked!", danger: "It failed." }
    => {:success=>"It worked!", :danger=>"It failed."}
    >> flash.each do |key, value|
    ?>   puts "Key #{key.inspect} has value #{value.inspect}"
    >> end
    Key :success has value "It worked!"
    Key :danger has value "It failed."
    
  41. inspect method, which returns a string with a literal representation of the object it’s called on:回傳strinf,會連"":都顯示出來

    >> puts (1..5).to_a            # Put an array as a string.
    
    1
    2
    3
    4
    5
    >> puts (1..5).to_a.inspect    # Put a literal array.
    
    [1, 2, 3, 4, 5]
    >> puts :name, :name.inspect
    name
    :name
    >> puts "It worked!", "It worked!".inspect
    It worked!
    "It worked!"
    

    inspect 可以用p來代替

    >> p :name             # Same output as 'puts :name.inspect'
    
    :name
    
  42. 重新看一次CSS:

    <%= stylesheet_link_tag 'application', media: 'all',
    'data-turbolinks-track' => true %>
    
    stylesheet_link_tag 'application', media: 'all',
    'data-turbolinks-track' => true
    
  43. parentheses are optional, so these two are equivalent:

    stylesheet_link_tag('application', media: 'all',
                                   'data-turbolinks-track' => true)
    
    stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track' => true
    
  44. hashes 是最後一個變數的時候,可以省略:

    stylesheet_link_tag 'application', { media: 'all',
                                     'data-turbolinks-track' => true }
    
    stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track' => true
    
  45. 'data-turbolinks-track' => true 還是用舊的寫法,主要是因為-不能用在symbol裡:

    'data-turbolinks-track' => true
    
  46. 這樣的斷行方式比較好閱讀,一行最好是少於80的字母。

    stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track' => true
    
    stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track' => true
    
  47. Because of the <%= %> brackets, the results are inserted into the template by ERb, and if you view the source of the page in your browser you should see the HTML needed to include a stylesheet (Listing 4.11).

    <link data-turbolinks-track="true" href="/assets/application.css" media="all"
    rel="stylesheet" />
    
  48. 開始講classes

  49. String的做法:

    >> s = "foobar"       # A literal constructor for strings using double quotes
    
    => "foobar"
    >> s.class
    => String
    
    >> s = String.new("foobar")   # A named constructor for a string
    
    => "foobar"
    >> s.class
    => String
    >> s == "foobar"
    => true
    
  50. Arrays的做法:

    >> a = Array.new([1, 3, 2])
    => [1, 3, 2]
    
  51. Hashes的做法:可以定義不存在的key的value - 在new的時候先給予值

    >> h = Hash.new
    => {}
    >> h[:foo]            # Try to access the value for the nonexistent key :foo.
    
    => nil
    >> h = Hash.new(0)    # Arrange for nonexistent keys to return 0 instead of nil.
    
    => {}
    >> h[:foo]
    => 0
    
  52. 可以用在Class的method = class method
    Class new 出來的東西,叫做instance of the class
    instance of the class的method = instance method
    When a method gets called on the class itself, as in the case of new, it’s called a class method. The result of calling new on a class is an object of that class, also called an instance of the class. A method called on an instance, such as length, is called an instance method.

  53. 講superclass method:

    >> s = String.new("foobar")
    => "foobar"
    >> s.class                        # Find the class of s.
    
    => String
    >> s.class.superclass             # Find the superclass of String.
    
    => Object
    >> s.class.superclass.superclass  # Ruby 1.9 uses a new BasicObject base class
    
    => BasicObject
    >> s.class.superclass.superclass.superclass
    => nil
    

  54. 自己弄一個word的class來試看看
    Let’s make a Word class with a palindrome? method that returns true if the word is the same spelled forward and backward:

    >> class Word
    >>   def palindrome?(string)
    >>     string == string.reverse
    >>   end
    >> end
    => :palindrome?
    

    We can use it as follows:

    >> w = Word.new              # Make a new Word object.
    
    => #<Word:0x22d0b20>
    
    >> w.palindrome?("foobar")
    => false
    >> w.palindrome?("level")
    => true
    
  55. Since a word is a string, it’s more natural to have our Word class inherit from String, as seen in Listing 4.12.

    >> class Word < String             # Word inherits from String.
    
    >>   # Returns true if the string is its own reverse.
    
    >>   def palindrome?
    >>     self == self.reverse        # self is the string itself.
    
    >>   end
    >> end
    => nil
    
  56. Word < String is the Ruby syntax for inheritance

    >> s = Word.new("level")    # Make a new Word, initialized with "level".
    
    => "level"
    >> s.palindrome?            # Words have the palindrome? method.
    
    => true
    >> s.length                 # Words also inherit all the normal string methods.
    
    => 5
    
    >> s.class
    => Word
    >> s.class.superclass
    => String
    >> s.class.superclass.superclass
    => Object
    

  57. self: word is its own reverse involves accessing the word inside the Word class. Ruby allows us to do this using the self keyword: inside the Word class, self is the object itself, which means we can use

    self == self.reverse
    
  58. inside the String class the use of self. is optional on a method or attribute (unless we’re making an assignment), sow ould work as well.

    self == reverse
    
  59. 在Ruby,我們可以自己修改既有的class裡面的method

    >> "level".palindrome?
    NoMethodError: undefined method `palindrome?' for "level":String
    
    >> class String
    >>   # Returns true if the string is its own reverse.
    
    >>   def palindrome?
    >>     self == self.reverse
    >>   end
    >> end
    => nil
    >> "deified".palindrome?
    => true
    
  60. blank 跟 empty是不一樣的

    >> "".blank?
    => true
    >> "      ".empty?
    => false
    >> "      ".blank?
    => true
    >> nil.blank?
    => true
    
  61. Note also that nil is blank; since nil isn’t a string, this is a hint that Rails actually adds blank? to String’s base class, which (as we saw at the beginning of this section) is Object itself.

  62. A controller class

    class StaticPagesController < ApplicationController
    def home
    end
    def help
    end
    def about
    end
    end
    
  63. StaticPagesController is a class that inherits from ApplicationController, and comes equipped with home, help, and about methods

    >> controller = StaticPagesController.new
    => #<StaticPagesController:0x22855d0>
    
    >> 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
    

  64. 因為home method裡面我們沒有寫東西,所以是nil。
    Here the return value is nil because the home action is blank.

    >> controller.home
    => nil
    

    But wait—actions don’t have return values, at least not ones that matter. The point of the home action, as we saw in Chapter 3, is to render a web page, not to return a value. And I sure don’t remember ever calling StaticPagesController.new anywhere. What’s going on?
    What’s going on is that Rails is written in Ruby, but Rails isn’t Ruby. Some Rails classes are used like ordinary Ruby objects, but some are just grist for Rails’ magic mill. Rails is sui generis, and should be studied and understood separately from Ruby.

  65. 用example_user.rb取代console去產生user

    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
    
  66. attr_accessor :name, :email
    透過 instance variables(@name@email)可以存取(“getter” 和 “setter”)用戶的nameemail
    instance variables可以直接用在view裡面
    creates attribute accessors corresponding to a user’s name and email address. This creates “getter” and “setter” methods that allow us to retrieve (get) and assign (set) @name and @email instance variables.
    In Rails, the principal importance of instance variables is that they are automatically available in the views, but in general they are used for variables that need to be available throughout a Ruby class. (We’ll have more to say about this in a moment.) Instance variables always begin with an @ sign, and are nil when undefined.
    initialize就是new的意思:

    def initialize(attributes = {})
        @name  = attributes[:name]
        @email = attributes[:email]
    end
    

    initialize(attributes = {})預設值是一個空的hash,因此用戶可以不用輸入name跟email
    4.3.3:如果key不存在,Hash會回傳nil。(看下面的例子)
    Here the attributes variable has a default value equal to the empty hash, so that we can define a user with no name or email address. (Recall from Section 4.3.3 that hashes return nil for nonexistent keys, so attributes[:name] will be nil if there is no :name key, and similarly for attributes[:email].)

    def formatted_email
        "#{@name} <#{@email}>"
    end
    
    >> require './example_user'     # This is how you load the example_user code.
    
    => true
    >> example = User.new
    => #<User:0x224ceec @email=nil, @name=nil>
    
    >> example.name                 # nil since attributes[:name] is nil
    
    => nil
    >> example.name = "Example User"           # Assign a non-nil name
    
    => "Example User"
    >> example.email = "user@example.com"      # and a non-nil email address
    
    => "user@example.com"
    >> example.formatted_email
    => "Example User <user@example.com>"
    

    example.name = "Example User"
    將@name設定為"Example User"

    >> user = User.new(name: "Michael Hartl", email: "mhartl@example.com")
    => #<User:0x225167c @email="mhartl@example.com", @name="Michael Hartl">
    
    >> user.formatted_email
    => "Michael Hartl <mhartl@example.com>"
    
← ROR TUTORIAL (3RD ED.) Ch3 Mostly static pages ROR TUTORIAL (3RD ED.) Ch5 Filling in the layout →