读高见龙的《为你自己学Ruby on Rails》前半部分提取笔记

写在前面:这里的提取是个人提取(只记录不知道的东西)。

电子书地址:http://railsbook.tw/

提示:在学RUBY基础时,有时不要把它和rails混在一起思考。先有ruby才有rails,ruby不了解rails,但rails很了解ruby....

开发工具和常用指令

  1. 如果出门在外,忘了带mac,怎么写代码???答案是可以用三线编辑器:

    后两款:自带开发环境!!!!

  2. 常用指令:

    • sudo 暂时取得权限

第一个应用程式

  1. scaffold的作用:自动完成增删改查的功能,包括MVC。

  2. 在新增migration时,数据类型string可以省略(因为是默认)。

  3. N+1查询问题,就是会额外查询关联的资料库,对系统资源很浪费)。解法:

    • includes来减少不必要的资料库查询。

        def index
          @posts = Post.all
        end
      

      改成:(里是关联了user)

        def index
          @posts = Post.includes(:user)
        end
      

變數、常數、流程控制、迴圈

  1. 如果想交换x,y两个变数的值,怎么写最ruby???

    x, y = y, x
    
  2. if可以放到程式的后面(这样读起来更像英文文章)

    a=1 if b > a #如果b > a,那么a = 1
    
  3. 三元连算�子:(if ….. else …..这个语法放到同一行)

    if a > b 
      a = 1
    else
      a = 2
    end
    
    #上面的程式码,可以压缩成一行:
    a > b ? a = 1 : a = 2
    
    #帅到掉渣,有木有!
    

數字、字串、陣列、雜湊、符號

  1. 注意= ==的问题。一个是赋值,一个是比较!

  2. 整数的除法,其中一个数为小数,结果才为小数。

  3. 取余数%

    • 判断是否为单数:.odd?
    • 判断是否为复数: .even?
  4. 四舍五入.round(x)

  5. 字串中要插入变量,可以用#{}!!!

  6. 字串可以直接当成数组来用,取字。

  7. 如何获得字串的长度:

    • 长度: .size
    • 字节: .bytesize
  8. 计算几个字几个单词: .sqlite.count

  9. 大小写转换:

    • 转大写: upcase
    • 转小写: downcase
  10. 对比首尾字母:

    • start_with?
    • end_with?
  11. 替换掉其中的片段:

    • 只换第一个: sub
- 全部换掉:`gsub`

```
  puts "PHP is good, and I love PHP".sub(/PHP/, "Ruby")
  # sub 只會換掉最先遇到的那個字串
  # => 印出「Ruby is good, and I love PHP」

  puts "PHP is good, and I love PHP".gsub(/PHP/, "Ruby")
  # gsub 會換掉全部符合的字串
  # => 印出「Ruby is good, and I love Ruby」
```
  1. map方法示例:

      list = [1, 2, 3, 4, 5]
      p list.map { |i| i * 2 - 1 }    # [1, 3, 5, 7, 9]
    
  2. reduce方法示例:(只作数值与index的运算)

     puts [*1..100].reduce(:+)
    
  3. select方法示例:(相当于一个过滤器)

     p [*1..100].select(&:odd?)
    
  4. 取随机数的方法:

    • shuffle洗牌:

      puts [*1..52].shuffle.first(5)
      
    • sample不重复的乱数:

      puts [*1..100].sample(5)
      
  5. object_id可以检测是否同一物件。

  6. 什么是symbol<u>一个带有名字的物件</u>(其他物件都没有名字,只有它有)

  7. stringsymbol的对比:

    • string可以被改变,symbol不行
    • symbol可以直接从内存中取得相同的东西,不会像string总是新建物件,所以一定程度上symbol是比较省内存的。
    • symbol的比较会比string快!
    • string和symbol是可以相互转换的!

方法與程式碼區塊(block)

  1. 在 Ruby 執行方法,經常省略小括號,目的是為了讓程式碼看起來更不像程式碼,反而像是一般的文章。

  2. 定义方法时,可以加个预设值:

      def say_something(message = "something")
        "message: #{message}"
      end
    
      p say_something "hi"     # => message: hi
      p say_something          # => message: something
    
  3. ruby很爱省略小括号和大括号,这里日后可能会掉坑~

  4. 什么是程式码区块

    { ... } 以及 do ... end,在 Ruby 稱之一個程式碼區塊(Block)

  5. 程式码区块不是:

    • 不是物件:无法单独存在

    • 不是参数:无法当参数,放在方法后一般不会执行。要如何才能执行:

        def say_hello
          puts "開始"
          yield          # 把控制權暫時讓給 Block
          puts "結束"
        end
      
        say_hello {
          puts "這裡是 Block"
        }
      

      6666,原来这两个地方都可以传参数……:

        def say_hello
          puts "開始"
          yield 123         # 把控制權暫時讓給 Block,並且傳數字 123 給 Block
          puts "結束"
        end
      
        say_hello { |x|     # 這個 x 是來自 yield 方法
          puts "這裡是 Block,我收到了 #{x}"
        }
      
  6. <u>block的物件化:</u>

      say_hello_to = Proc.new { |name| puts "你好,#{name}"}
      say_hello_to.call("尼特羅會長")
      
      say_hello_to.call("尼特羅會長")    # 使用 call 方法
      say_hello_to.("尼特羅會長")        # 使用小括號(注意,有多一個小數點)
      say_hello_to["尼特羅會長"]         # 使用中括號
      say_hello_to === "尼特羅會長"      # 使用三個等號
      say_hello_to.yield "尼特羅會長"    # 使用 yield 方法
    

類別(Class)與模組(Module)

类别
  1. 什么类别:

    物件(object) = 狀態(state) + 行為(behavior)

    一个精妙的类比:

    不知道大家有沒有在夜市有看過或吃過雞蛋糕,有小貓、小狗等可愛動物造型,只要把調配好的麵粉糊倒進模具,蓋上蓋子,幾分鐘後就會有香噴噴又造型可愛的雞蛋糕可以吃了。

    image
    photo by Bryan Liu

    那個烤盤模具,就是類別(Class)的概念。如果沒意外,一樣形狀的模具,放一樣的原料進去,做出來雞蛋糕的型狀應該都會長得一樣。而這個做出來的雞蛋糕,以物件導向程式設計的概念來說便稱之「實體(Instance)」。

  2. 传参数初始化:

      class Cat
        def initialize(name, gender)
          @name = name
          @gender = gender
        end
    
        def say_hello
          puts "hello, my name is #{@name}"
        end
      end
    
      kitty = Cat.new("kitty", "female")
      kitty.say_hello    # => hello, my name is kitty
    
  3. attr_accessor的作用:

    帮助设定和取用实体变数的值!(ruby没有【属性】一说!)

    所以,以下这个:

      class Cat
        def initialize(name, gender)
          @name = name
          @gender = gender
        end
    
        def say_hello
          puts "hello, my name is #{@name}"
        end
    
        def name
          @name
        end
    
        def name=(new_name)
          @name = new_name
        end
      end
    
      kitty = Cat.new("kitty", "female")
      kitty.name = "nancy"
      puts kitty.name        # => nancy
    

    可以直接变成:

      class Cat
        attr_accessor :name
    
        def initialize(name, gender)
          @name = name
          @gender = gender
        end
    
        def say_hello
          puts "hello, my name is #{@name}"
        end
      end
    

    有了这个设定后,我们就可以直接用这个参数,像属性一样方便用!!!

  4. 什么实体方法,什么是类别方法:

    • 作用在实体上的方法,叫做:实体方法。

    • 作用在类别上的方法,叫做:类别方法。这个有几种表现:

      • class Cat
          def self.all
            # ...
          end
        end
        
      - ```
          class Cat
            class << self
              def all
                # ...
              end
            end
          end
      

      有很多类别方法时,可以用这种!

  5. 继承:可以让代码更简洁

  6. open class: 可以方便地为方法“加料”!

  7. 如果想要分开定义一些方法,可以用到模组,方法:

      module Flyable
        def fly
          puts "I can fly!"
        end
      end
    
      class Dog
        include Flyable
      end
    
  8. 模组和类别的不同之处:

    • 模组没办法new一个新的实体出来。
    • 模组没办法继承别的模组。
  9. 定义外部键时,使用references来自动增加外部键:

    rails g model post user:references
    

    这样,references会做多两件事:

    1. 自动加上索引,加快查询速度。
    2. 自动帮model加入关联。

Layout,Render 與 View Helper

  1. 在特定的controller 的action里,如何你想用不同的layout可以这样:

      class CandidatesController < ApplicationController
    
        def index
          @candidates = Candidate.all
          render layout: "backend"
        end
    
        # ...[略]...
      end
    
  2. 如果想给每个页面定义网页title,这个好!可以这样做:

    • 方法1:使用 provide:
      <!DOCTYPE html>
      <html>
        <head>
          <title><%= yield :my_title %></title>
          <%= csrf_meta_tags %>
          <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
          <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
        </head>
    
        <body>
          <div class="container">
          <%= yield %>
          </div>
        </body>
      </html>
    
      <% provide :my_title, "你好,我是 Title" %>
    
      <h1>候選人列表</h1>
    
      <%= link_to "新增候選人", new_candidate_path %>
    
      <table class="table">
        <thead>
          <tr>
            <td>投票</td>
            <td>候選人姓名</td>
      ...[略]...                                      
    
    • 使用 content_for:
      <% content_for :my_title do %>
      你好,我是 Title
      <% end %>
    
      <h1>候選人列表</h1>
    
      <%= link_to "新增候選人", new_candidate_path %>
    
      <table class="table">
        <thead>
          <tr>
            <td>投票</td>
            <td>候選人姓名</td>
      ...[略]...
    
  3. 更好地用render:

    • partial里尽量用区域变量。
    • 使用时再传递这个变量。

    例子:

      <div class="advertisement">
        <div>廣告</div>
        <div> <%= content %> </div>
      </div>
    
      <%= render "banner", content: "我是廣告的內容" %>
    
    • partial里有一个collection的方法,使用时传递这个参数,就可以迭代输出partial。(回圈效果)
      <%= render partial: "candidate", collection: @candidates %>
    

    这里还可以简化成:

      <%= render @candidates %>
    

    但要满足以下条件:(利用了rails的惯例)

    • _xxx.html.erb的名字必须是这包资料的<u>单数</u>
    • 位置必须放在同一目录下。
    • _xxx.html.erb里不要写回圈,里面的区域变数必须是单数。
  4. 善用View Helper !

待续……

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容

  • # The Ruby Style Guide > Hey jude, don't make it bad. > T...
    司徒雷斯阅读 322评论 0 2
  • Scala与Java的关系 Scala与Java的关系是非常紧密的!! 因为Scala是基于Java虚拟机,也就是...
    灯火gg阅读 3,429评论 1 24
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,646评论 18 139
  • 基础1.r''表示''内部的字符串默认不转义2.'''...'''表示多行内容3. 布尔值:True、False(...
    neo已经被使用阅读 1,670评论 0 5
  • 感恩,早晨有妈妈做的早餐,感恩早餐前的惊险,幸好老公起床闻到特殊的味道,赶紧跑到厨房,原来妈妈接电话,却忘了关火,...
    佳音妈阅读 411评论 0 0