回顾知识点

1. 在application.html.erb中: <main class="<%= controller.controller_name%>"> 的controller.controller_name是怎么理解?

查api:ActionController::Metal中的实例方法controller_name,

def controller_name

self.class.controller_name   #=> 里面调用同名类方法

end

思考:应用模版是根据请求的controller来渲染的,所以这里的controller应该是products.

尝试:在products/index.html.erb中,输出 <h1><%= controller %></h1>得到:实例化的对象#<ProductsController:0x00007fafcc72d070>,所以它的类是ProductsController,然后调用同名类方法,看源码,就是用正则表达式返回string。

def self.controller_name
@controller_name ||= name.demodulize.sub(/Controller$/, "").underscore
end 

解析: ProductsController.name => "ProductsController"

"ProductsController"  => 去掉继承的父类字符,还是 "ProductsController"

然后调用sub()把最后的字符串,替换为空。 => "Product"

再用underscore(),在大写字符前加下划线,然后改成小写 => "product"

结论: <main class="<%= controller.controller_name%>">相当于<main class="product">,调用css样式,对应在products.scss


ActionView::Helpers::SanitizeHelper(消毒,净化)

The SanitizeHelper module provides a set of methods for clean text of undesired HTML elements. These helper methods extend Action View making them callable within your template files. 4个方法。

sanitize(html, options = {}) ,可以加白名单


scss:用于编译成html认识的css (详细)

li {

...

      &::after {
        clear:both;
        content: " ";
        display: block;
      }

}

complied:

li {...}

li::after{...}

::after是psesudo element 一般用于在某个元素后面添加content:"xxx"内容,这里应该是用在li的循环在li之间加一个空行。

The ampersand & in SASS pulls in the parent selector when it compiles to CSS.

什么是css伪元素A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s). For example, ::first-line can be used to change the font of the first line of a paragraph

/* The first line of every <p> element. */ 
p::first-line { color: blue; text-transform: uppercase; }

Responsive Web Design - Media Queries

Media query is a CSS technique introduced in CSS3.

It uses the @media rule to include a block of CSS properties only if a certain condition is true.

 
Desktop
Tablet

Phone


 

勘误《Rails5敏捷开发》:cache  P115 缓存局部结果

缺少一段翻译,和关键的一行代码:5.1版原文如下:

As far as verifying that this works is concerned, you’re going to get some insight into the work the server is doing behind the scenes. Go back to your server window and watch what happens when you refresh the page. The first time you load the page, you should see some SQL that is loading the products like Product Load (0.2ms) SELECT "products".* FROM "products" ORDER BY "products"."title" ASC. When you refresh the page again, it will still work, but you won’t see that SQL run. You should see some SQL that Rails runs to check if its cache is outdated, like so: SELECT COUNT(*) AS "size", MAX("products"."updated_at") AS timestamp FROM "products".
If you still aren’t convinced, you can add a configuration option to config/environments/development.rb called enable_fragment_cache_logging, like so:
​ ​# Enable/disable caching. By default caching is disabled.​
​ ​if​ Rails.root.join(​'tmp/caching-dev.txt'​).exist?
»   config.action_controller.enable_fragment_cache_logging = ​true​
​   config.action_controller.perform_caching = ​true​
You’ll need to restart your server for this to take effect, but after doing that, you should see log messages that look like this:
Read fragment views/products/4-20180409121532794883/382d59eb4358e2ff3dde9ec3a35ca386 (0.0ms)
Write fragment views/products/4-20180409121532794883/382d59eb4358e2ff3dde9ec3a35ca386 (0.0ms)
Write fragment views/products/query-b41f6fbd1a3876c26c349b7e6dd13d56-3-20180409121532797255/382d59eb4358e2ff3dde9ec3a35ca386 (0.0ms)

⚠️: 这篇博客有详细的案例讲解HTTP cache, fragment cache:

rails默认提供fragment caching。

action caching和page caching需要手动设置:

增加2个gem:actionpack-page_caching和actionpack-action_caching 具体做法需要看文档的连接。

默认情况下,缓存只在生产环境启动,如果想在本地启动缓存,需要:

在config/environments/*.rb中一般是developemnt.rb中:

config.action_controller.enable_fragment_cache_logging = ​true​

如代码所写,缓存只影响action controller,对底层缓存无影响。

片段缓存:

“片段缓存把视图逻辑的一部分放在 cache 块中,下次请求使用缓存存储器中的副本伺服。”

首次访问这个页面时,Rails会创建 一个时间戳(对象的id加updated_at属性),如果updated_at变化了则生成新的键然后写入一个新的缓存。

cache_if/cache_unless方法可以用于特定的条件。

示例:集合缓存,一次性缓存,速度更快。

<%= render partial:'products/product', collection:@products, cache: true %>

示例:片段缓存,

<% @products.each do |product| %>

  <% cache product do %>
    <%= render product %>
  <% end %>
<% end %> 

rails dev:cache 在开发/测试环境打开/关闭缓存

在关联的模型上,如果视图有嵌套,在belongs_to 后加,touch:true,同步判断缓存是否失效。

有时,可能想把缓存的片段嵌套在其他缓存的片段里。这叫俄罗斯套娃缓存(Russian doll caching)。
俄罗斯套娃缓存的优点是,更新单个商品后,重新生成外层片段时,其他内存片段可以复用。

如果缓存的文件对应的记录的 updated_at 属性值变了,缓存的文件失效。但是,内层嵌套的片段不失效。

对下面的视图来说:

<% cache product do %>
  <%= render product.games %>
<% end %>

而它渲染这个视图:


<% cache game do %>
  <%= render game %>
<% end %>”
 

如果game的任何一个属性变了,updated_at 的值会设为当前时间,因此缓存失效。然而,project对象的 updated_at 属性不变,因此它的缓存不失效,从而导致应用伺服过期的数据。为了解决这个问题,可以使用 touch
方法把模型绑在一起:

class Product < ApplicationRecord
has_many :games
end
class Game < ApplicationRecord
  belongs_to :product, touch: true
end 
这样就同步失效了。目的是让

管理依赖:有时候对需要处理自定义的helper methods,要自定义缓存依赖.

比如自定义的集合:
render @project.documents.where(published: true)
需要改为标准格式:
render partial: "documents/document", collection: @project.documents
  .where(published: true), cache:true

Explicit dependency
External dependency
这两个没有弄明白。http://guides.rubyonrails.org/caching_with_rails.html#shared-partial-caching


底层缓存:

缓存特定的值或者query结果。使用Rails.cache.fetch方法 ,详细用法看api.

ActiveSupport::Cache::Store可以储存任何可串联的Ruby对象。

基本的缓存方法:

fetchwritereadexist?, and delete

keys会被转化为string.

cache = ActiveSupport::Cache::MemoryStore.new

cache.write("city", "Duckburgh")

cache.read("city")  #=> "Duckburgh"

fetch(name, options = nil)

使用给定的key从缓存取数据。如果有对应的数据,返回这个数据。

如果没有对应的数据,返回nil。

如果一个block被传入, key先在缓存中找对应数据,如果找不到,则把block中的数据作为这个key的数据写入缓存,并返回block中的数据。

option选择有多个,如expires_in: 12.hours 在12小时后缓存到期.  namespace则用于创建命名空间防止与其他应用共用一个缓存存储器。

下面是个Product模型,有个实例方法,在竞争网站查找某个商品的价格。

class Product < ApplicationRecord
  def competing_price
    Rails.cache.fetch("#{cache_key}/competing_price", expires_in: 12.hours) do
      Competitor::API.find_price(id)
    end
  end
end 

SQL缓存

Rails提供的功能,如果在同一请求中遇到相同的查询结果,rails会使用缓存的结果。⚠️的是SQL缓存机制只在一个动作内有效,如果这个动作结束,缓存也就销毁了。如果想持久储存查询结果,可以使用

4-10 辅助方法controll_name,;SanitizeHelper; 伪元素和scss中的&, @Media; cache介绍。的更多相关文章

  1. MVC中使用内建的HTML辅助方法产生表单元素提交表单与button按钮事件的陷阱

    网站模板页有个登陆的退出按钮,当点击时跳转到登陆页面. <button onclick="logout()" >退出</button> $("#l ...

  2. 使用::befor和::after伪元素在网站中添加图标

    css3为了区分伪类和伪元素,伪元素采用双冒号写法. 常见伪类——:hover,:link,:active,:target,:not(),:focus. 常见伪元素——::first-letter,: ...

  3. 深入理解脚本化CSS系列第六篇——脚本化伪元素的6种方法

    × 目录 [1]动态样式 [2]CSS类[3]setAttribute()[4]CSSRule对象添加[5]空样式覆盖[6]CSSRule对象删除 前面的话 我们可以通过计算样式来读取伪元素的样式信息 ...

  4. 使用JS控制伪元素的几种方法

    一. 缘由: 本文源于在OSC社区中,有人提问如何用jq获取伪元素.我第一想法是强大的CSS Query应该可以获取伪元素吧. 然而事实上,CSS Query并不能.即我们不能通过$(":b ...

  5. 《ASP.NET MVC高级编程(4版)》读书笔记(5)表单和HTML辅助方法

    5.1 表单使用 5.1.1 action 和 method 特性 <form action="/Home/Index">     <input name=&qu ...

  6. ASP.NET MVC3学习心得-----表单和HTML辅助方法

    5.1表单的使用 5.1.1  action和method的特性 表单是包含输入元素的容器,包含按钮.复选框.文本框等元素,表单的这些输入元素使得用户能够向页面中输入信息,并把输入信息提交给服务器.A ...

  7. asp.net mvc 3.0 知识点整理 ----- (3).HtmlHelper(Html 辅助方法)介绍

    在View视图中,Html的类型是System.Web.Mvc.HtmlHelper<T>, 所有的辅助方法都需要和ModelState交互.那么,ModelState是什么呢?它是模型绑 ...

  8. css3 伪元素和伪类选择器详解

    转自脚本之家:http://www.jb51.net/css/213779.html 无论是伪类还是伪元素,都属于CSS选择器的范畴.所以它们的定义可以在CSS标准的选择器章节找到.分别是 CSS2. ...

  9. 【CSS进阶】伪元素的妙用2 - 多列均匀布局及title属性效果

    最近无论是工作还是自我学习提升都很忙,面对长篇大论的博文总是心有余而力不足,但又不断的接触学习到零碎的但是很有意义的知识点,很想分享给大家,所以本篇可能会很短. 本篇接我另一篇讲述 CSS 伪元素的文 ...

随机推荐

  1. CHM无法正常显示的问题

    很喜欢看CHM电子书,感觉篇幅不是很长,而且可以索引:但是昨天遇到这个问题: 打开文件的时候发现: 很喜欢看CHM电子书,感觉篇幅不是很长,而且可以索引:但是昨天遇到这个问题: 打开文件的时候发现: ...

  2. 新版.Net开发必备十大工具(转)

    Snippet Compiler Snippet Compiler是一个基于 Windows 的小型应用程序,你可以通过它来编写.编译和运行代码.如果你具有较小的代码段,并且你不想创建完整的 Visu ...

  3. 网络营销相关缩写名称CPM CPT CPC CPA CPS SEM SEO解析

    网络营销相关缩写名称CPM CPT CPC CPA CPS SEM SEO解析 CPM CPT CPC CPA CPS SEM SEO在网络营销中是什么意思?SEO和SEM的区别是? CPM(Cost ...

  4. C++:struct和union 内存字节对齐问题

    转自:http://blog.csdn.net/wangyanguiyiyang/article/details/53312049 struct内存对齐问题 1:数据成员对齐规则:结构(struct) ...

  5. 含有虚函数的类sizeof大小

    #include <iostream> using namespace std; class Base1{ virtual void fun1(){} virtual void fun11 ...

  6. 20144303石宇森《网络对抗》MSF基础应用

    20144303石宇森<网络对抗>MSF基础应用 实验后回答问题 一.解释什么是exploit,payload,encode: 我认为exploit就是一个简单的攻击指令,就是对配置所有设 ...

  7. 20165310_获奖感想与Java阶段性学习总结

    获奖感想与Java阶段性学习总结 一.Learning By Doing ​ 在此之前,其实我并没有想到能够成为小黄杉的第一批成员之一,喜悦之余,也感受到了许多的压力.小黄杉一方面代表了老师对于我这一 ...

  8. 《将博客搬至51CTO》

    想把你的博客搬家到51CTO吗?想拥有一键式搬家的体验吗? 就算家大业大不好搬也没关系,我们帮你! 51CTO推出专业的搬家工具,用最短的时间.最快的速度,为你在这儿搭建一个温馨的家. 在这儿,你可以 ...

  9. 平衡树之伸展树(Splay Tree)题目整理

    目录 前言 练习1 BZOJ 3224 普通平衡树 练习2 BZOJ 3223 文艺平衡树 练习3 BZOJ 1588 [HNOI2002]营业额统计 练习4 BZOJ 1208 [HNOI2004] ...

  10. POJ 1830 开关问题(高斯消元)题解

    思路:乍一看好像和线性代数没什么关系.我们用一个数组B表示第i个位置的灯变了没有,然后假设我用u[i] = 1表示动开关i,mp[i][j] = 1表示动了i之后j也会跟着动,那么第i个开关的最终状态 ...