来源:https://www.gitbook.io/book/rocodev/rails-102

Scope

Scope的作用就是将时常使用或者复杂的ORM语法组合成懒人包,这样下次使用就可以直接拿过来使用。
例子:

class Topic < ActiveRecord::Base
    scope :recent, -> { order("create_at DESC") }
end

使用情境:

  • 当过于复杂的资料查询
  • 当有重复使用的资料查询

使用方式

  1. 没有带参数的方式

    class Post < ActiveRecord::Base
    scope :published, -> { where(published: true) }
    end

  2. 带有参数的方式

    class Post < ActiveRecord::Base
    scope :created_before, ->(time) { where("created_at < ?", time) }
    end

  3. 可以串接在一起,顺序没有影响

    class Event < ActiveRecord::Base
    scope :published, -> { where(published: true) }
    scope :created_before, ->(time) { where("created_at < ?", time) }
    end

使用方法:Event.published.created_before(Time.now)

includes

当我们在操作关联性资料时,可以使用includes将关联性资料先抓出来,每次要调用资料时就不是去资料库搜寻了,而是从已经调阅出来的资料里搜寻,可以提供效能。
假设Board has_many Tpoics

class Board < ActiveRecord::Base
    def index
        @boards = Board.all
    end
end

假定我们有10条board,在view里面我们使用

<% @boards.each do |board| %>
    <% borad.topics.each do |topic| %>
        <%= topic.title %>
    <% end %>
<% end %>

这样子的做法有一个很不好的地方那个就是我们需要重复查询数据库10次,增加了渲染时间。
若是加上includes后会是这样子

class Board < ActiveRecord::Base
    def index
        @borads = Board.includes(:topics).all
    end
end

这时候我们在view里面使用时

  1. 到数据库把boards的所有topics都提取出来
  2. 提取出来的topic中找到board_id相对应的topic
    这样我们就只需要搜寻一次,直接减少了数据库的负担。

counter_cache

counter_cache 是在做关联性数据库时计算数据量的一个方法。
假如:Board has_many Topics,一般我们的写法如下:

@board.topics.count

这种方法就是我们要计算topic的数量时都需要下一个sql指令去计算topic的数量,一样会对性能有影响。

我们可以使用Rails内建的counter_cache的方法,我们只需要Topic model内加上counter_cache: true
class Topic < ActiveRecord::Base
belongs_to :board, counter_cache: true
end

然后在Board的表中新增topics_count字段。我们就可以直接使用@board.topics_count来代替@board.topics.count

自定义字段:
例如将topics_count改成count_of_topics
class Topic < ActiveRecord::Base
belongs_to :board, counter_cache: :count_of_topics
end


天赢金创
338 声望21 粉丝

天赢金创,天赢金创,天赢金创,天赢金创,天赢金创,天赢金创天赢金创,天赢金创


引用和评论

0 条评论