TimYang 老师有一篇关于分页的文章供参考: 用 Twitter 的 cursor 方式进行 Web 数据分页
在数据比较多时,采用偏移量应该合适一些。设计缓存时确实得细心一些了。
#15 楼 @lin_style Rails 在找不到常量时,会根据这个常量的名字,加载文件。这确实是 Rails 的惯例。
大致的规则就是,如果类名(常量名、模块名都是常量)是 MaMbMc1::M2::M3
,那么就把 ::
替换为 '/',单词变成小写,并且之间用下划线_
连接,然后尝试在 ActiveSupport::Dependencies.autoload_paths
里的路径中,去查找是否有 ma_mb_mc1/m2/m3.rb
。如果有,那么就会去加载。
我记得 php 可以定义一个方法,在某个类找不到时,去加载某个文件。Rails 和这个大致类似吧。
如果模块名和文件名不一样,那根据上面的规则,肯定是加载不到这个文件的(因为根据模块名得到的文件名是不一致的)。 除非你在代码某个地方使用 require
已经加载了文件。
按照 Rails 的惯例, MaMbMc1::M2::M3
就应该定义在 ma_mb_mc1/m2/m3.rb
文件中。如果在 ma_mb_mc1/m2/m3.rb
中定义的是名为 Mx
的模块,那么第一次使用 MaMbMc1::M2::M3
常量时,就会抛出异常,告诉你 ma_mb_mc1/m2/m3.rb
应该定义 MaMbMc1::M2::M3
。
ActiveSupport::Dependencies.autoload_paths 默认只有 app/assets、app/helpers、app/controllers、app/mailers、app/models 这几个目录。你可以尝试一下,打开终端,输入
ActiveSupport::Dependencies.autoload_paths = []
然后随便输入模型的名字,Rails 都会报错 NameError: uninitialized constant xxx
。因为 Rails 加载模型,也是用 const_missing 机制的。
另外,Rails-2 和 Rails-3 不太一样。Rails-2 没有 ActiveSupport::Dependencies.autoload_paths
,而用了另外一个名字的属性。默认的路径里,不仅包括 lib 在内当前项目里的一些目录,还包括使用到的 gem 里的 lib 目录。
你是不是用的 Netbeans?
以前用 Netbeans 也找不到的。而且因为 .rvm 是隐藏目录,也无法手动添加。最后在网上搜了一下,在 ternimal 里启动 Netbeans 才找到的。
这个帖子,太 OT 了!
In HTML the <meta> tag has no end tag.
In XHTML the <meta> tag must be properly closed.
#10 楼 @lin_style 模块是不是定义在其他模块内?文件名是什么?
如果模块的 全名是 M,那么文件名 就是 m.rb。
Time#to_i
返回的是秒,最多是 (2**31 - 1)
,超过这个范围就溢出了:
>> Time.at(2**31 - 1)
=> Tue Jan 19 11:14:07 +0800 2038
>> Time.at(2**31)
RangeError: bignum too big to convert into `long'
from (irb):11:in `at'
from (irb):11
>> Time.at(2**31 - 1).utc
=> Tue Jan 19 03:14:07 UTC 2038
>> "20380119031407".to_time
=> Tue Jan 19 03:14:07 UTC 2038
>> "20380119031407".to_time.class
=> Time
>> "20380119031408".to_time.class
=> DateTime
>>
所以 String#to_time
的时候,超过 20380119031407 就是 Datetime 了。这个 Rails 干的。
我的电脑是 Linux/32 位,64 位可能最大不是这个。
字符串可以直接转成 Time 对象哦。
>> "20120514144424".to_time.strftime('%Y-%m-%d %H:%M:%S')
=> "2012-05-14 14:44:24"
lz 被苹果“毒害”很深哈。把 iPhone 写成 iphone,苹果是肯定不给审核通过的 ~
楼上正解。
lz 应该说一下,是如何加载 lib 目录下的文件的。
在 Rails 里有三种加载源码的方式:
require
,这个是 ruby 的方式。Abc::Def
,那么 Rails 就会尝试加载 abc/def.rb
这个文件。文件的搜索路径在 ActiveSupport::Dependencies.autoload_paths
中,可以在 application.rb 中用 config.autoload_paths
中添加。Rails-3 默认没有 'lib' 目录哦。所以默认情况下,使用这种方式加载不了。(load 也算一种,但似乎很少用)
使用第一种方式,应用启动后,只加载一次。使用后两种,在 development 模式下,每次处理新的请求,都会重新加载。
但是要注意,后两种加载的时候,会把源码所在的文件展开为绝对路径,再去 require
。所以,使用 Ruby-1.8.7 的时候要注意了:对于同一个文件,使用不同路径 require
文件,Ruby-1.8.7 会加载多次。所以项目中应该统一使用一种方式加载。
另外:如果想让 ActiveSupport::Dependencies.autoload_paths
中的某个目录的子目录只加载一次,可以添加到 config.autoload_once_paths
中。
#7 楼 @lin_style 原来 Rails 里有一个整个框架用的时区,还有一个 ActiveRecord 的默认时区。
#5 楼 @lin_style Rails 里的时区我还没完全搞懂。但希望能给你一些思路:
保存的时候,传递的是 Time.now
,是一个 Time
对象,但从数据库查出来对象后的时间,却是一个 ActiveSupport::TimeWithZone
对象。
假设在 Rails 的 config/application.rb 设置的时区是 Beijing,从数据库查出来的时间为 created_at
,那么 created_at.to_s(:db)
返回的时间,和用其他工具在数据库查看到时间一致,也就是滞后 8 小时;但created_at.to_s(:long)
返回的时间,却是本地时间。
created_at.localtime
返回的是本地时间。
查看 user.update_attribute("lastlogin_time", Time.now)
时的 SQL 语句,应该可以看到保存时间,是滞后八小时的时间。也就是 UTC 时间。
大致可以推测:
#localtime
才能得到本地时间。Rails-2 里,可能不是这样处理。
把 coffeescript 里定义的函数,绑到 window 上?
三个问题:
Rails-3 写数据库时,会转换成 UTC 时间。读取的时候,那得看怎么读了。记得 #to_s(:db)
会转换成 UTC 时间。其他的,可能是本地时间。
Rails-2 和 Rails-3 在时区处理上略有不同,但具体的我还没搞明白……
用的是 Passenger 2.0.3?好古老啊
我以前安装也失败了,记得 ruby-debug-base19 在 linux 和 mac 下安装的 gem 不一样。后来没用它。
#17 楼 @songlipeng2003 attr_accessor
是 ruby 里的,定义普通属性的(也就是 setter 和 getter 方法);attr_accessible
是 rails 里的,用来设置可以 mass-assignment 的属性。
attr_accessor :province, :city, :area, :address, :phone
这个定义了 5 个属性,应该用 attr_accessible
吧?
是不是因为 mass-assignment,那些属性无法被这样赋值?
是 rails 哪个版本呢,模型如何定义的?
我是不是可以理解:
如果你使用 ActiveSupport,那么试试 Hash#to_query
方法来生成查询串
{:q => "我是+中国人"}.to_query # => "q=%E6%88%91%E6%98%AF%2B%E4%B8%AD%E5%9B%BD%E4%BA%BA"
如果你没有使用 ActiveSupport,你可以看看其实现本质就是 CGI.escape("我是+中国人")
(在 Object#to_query
里)
我觉得一般情况下,模板引擎的性能不要特别考虑。因为一般都会用到缓存,而缓存编译过的片段(fragment)是最好的,纯字符串是大多数缓存的原生类型;如果做对象缓存,还得多一步序列化或反序列化,比较耗时。
仅仅是理论哈,我没有做过性能测试。
把 rails 当做入口,先了解 rails 能做什么,进一步学习是怎么做到的,逐步阅读 rails 源码,就会逐步深入 ruby 语言编程了。