豆知识
Turbolinks
Turbolinks 是一个 Javascript 套件,作用是使得网站在换页的时候,不重新载入 HTML 的 head
,只载入新的 body
,以此达到加速换页的目的。
但是 Turbolinks 有两个坑。
第一个坑
如果在页面中用了其他的 JavaScript 代码,并且用了类似 $(document).ready(function(){...})
这样的语句,意思是等待 HTML 载入完成后执行 js 的代码。这时的 turbolinks 就会使得这些 js 代码只会执行一次,也就是换页,再换回来的时候,这些 js 代码失效了。原因就是 turbolink 为了换页加速,不重新载入 HTML 的 head
代码。
解法是,改成 $(document).on("trbolinks:load", function(){...})
。
第二个坑
如果是写在 body
里的 js 代码,换页之后再换回来时,因为 turbolink 的机制,会使得这些 js 代码执行两次。
解法一:关掉 Turbolinks 的缓存功能,把 <meta name="turbolinks-cache-control" content="no-cache">
放到 layout 的 head
里面。
解法二:把layout 的<body>
改成<body id="<%= "#{controller_name}-#{action_name}"%>">
,这样就可以在全局载入的application.js
中指定只有这一页才执行的js code,例如:
终极解法
有一个终极解法,就是把 Turbolinks 拆掉。
第一步:修改 Gemfile,把 gem 'turbolinks'
删除;
第二步:在 application.js
里把 //= require turbolinks
删除;
第三步: 在 application.html.erb
里,把 <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
改成 <%= javascript_include_tag 'application' %>
to_param重写
调用路由方法的时候, Rails 默认用 to_param
方法来转换 ID,例如
event_path(@event)
等同于 event_path(@event.to_param)
to_param
是默认的方法,默认是这样定义的
def to_param
self.id
end
我们可以重定义,比如说在 event.rb
这个 model 里
def to_param
"#{self.id}-#{self.name}"
end
这样再次调用 event_path(@event)
时,出来的网址就会是 /events/xxx-name
的样子。
在 controller 里用了 @event = Event.find(params[:id])
,其中在调用 find
方法之前会先用 to_i
把 param[:id]
转换成纯数字,其中的非数字字符都会被忽略掉了。所以 controller 的原代码依然可用。
国际化
在 config/locales/application.rb
设置默认语言
class Application < Rails::Application
+ config.i18n.default_locale = "zh-CN"
end
国际化的相关 gem
gem "rails-i18n"
gem "devise-i18n"
在 config/locales
下增加设定档。
设定时区
在 config/locales/application.rb
设置
class Application < Rails::Application
+ config.time_zone = "Beijing"
end
还可以让用户在个人信息中选择自己的时区,然后在 application_controller.rb
加一个 set_timezone
的方法。
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :set_timezone
def set_timezone
if current_user && current_user.time_zone
Time.zone = current_user.time_zone
end
end
end
格式化时间
Ruby 内建了 strftime 这个方法来格式化输出,例如
<%= event.created_at.strftime("%Y/%m/%d %I:%M %p") %>
这样就会输出成例如 2017/04/10 05:53 PM
了。
除此之外,还可以用 to_s
来格式化时间,例如
datetime = Time.now
datetime.to_s(:db) # => "2007-12-04 00:00:00"
datetime.to_s(:number) # => "20071204000000"
datetime.to_s(:short) # => "04 Dec 00:00"
datetime.to_s(:long) # => "December 04, 2007 00:00"
datetime.to_s(:long_ordinal) # => "December 4th, 2007 00:00"
datetime.to_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
datetime.to_s(:iso8601) # => "2007-12-04T00:00:00+00:00"
to_s
的格式也可以自己定义,方法是在 config/application.rb
最后新增一行
Time::DATE_FORMATS.merge!(:default => '%Y/%m/%d %I:%M %p', :ymd => '%Y/%m/%d')
这样就会 1. 修改默认的时间显示格式 2. 注册一个新的格式是 ymd
只有日期。
<%= event.created_at.to_s %>
会输出 2017/04/10 05:53 PM
。
如果只想显示日期,可以改成 <%= event.created_at.to_s(:ymd) %>