@zacker330 我还真的不是从数据库开始思考的诶 :)
打比方如果写或者维护 ruby-china,那脑子就全部都是 Post, User, Comment。之间的关系都是 User has many comments, comment belongs to user。而不是 comments 表有一个 user_id 字段等等。
又比如说 repository model(我不知道具体的写法,只是假想),User 有一个 github repos 的数据,那么我就知道 User has many repos。至于这个 repos 是存在数据库里,还是直接从 github 获取,都不影响别的 model 和它直接的关系。
另外一个,schema.rb 是不能自己修改的。推荐的方法是通过 migration 来修改。
Martin Flower 的定义很明确啊
An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.
楼主的思维方式可能要改变。你是从数据库开始思考问题的。而一个应用应该是以 model 为中心思考。储存在数据库里只是 model 的一个存储方式而已,model 的存储也可以在内网其他应用,也可以是外部 API,也可以是一个文本文件,可以存在于很多地方。
正确的做法是
加多 CSS 标签。既不要针对 id 做样式,也最好不要轻易改动框架默认。
<div class="row top" id="a">
<div class="row bottom" id="b">
给新 CSS 标签设置样式
.top { margin-bottom: 10px; }
用 br 也是不可取的,如果你没有耗尽 CSS 的可能,就不要用 HTML 标签做样式。HTML 标签应该更多用在语义上。br 在这里没有任何语义。
bash 怎么会加载 zsh?你进入 zsh 应该在 console 里面直接设置而不是调整~/.bashrc 啊 :)
什么都不行就用系统自带的 GUI 文本编辑器吧,先把.bashrc 和.zshrc 纠正好了。
bash
vim ~/.zshrc
@ane, 这个不算。public method 里面可以随意使用 private methods, 毕竟 private methods 的主要目的之一就是为了 public methods 服务的。你可以直接def call_pri; pri; end
,都没有必要 send。
我觉得你没有必要为了这一句话纠结,等看到了具体代码部分再详细讨论比较有价值。
/posts 直接到 PostsController#index,是 posts 列表,不是具体的哪个了。
params[:post_id]
就会告诉你他们在哪个 post 下面。这个参数是在路径里面的 /post/:post_id/comment/:id
看看是不是 secrets.yml 里面哪里把 tab 当成空格了。要是用 vim 就:/s\t
查找。
meta programming 在这里有些滥用了
要是就那么几个简单设定,没有任何 association 的话不如直接写在程序 yml 里作为设定,没有必要进入数据库。
要是你的应用类似于建站工具,每个用户都有设定的话,可以把所有 setting 作为一个字段 serialize,然后直接从 hash 里面取任何值。
@bwlinux 好啊,问题被发现了:)测试的时候一切外部网络依赖都应该被 mock 掉,如果比较复杂的外部 API 还可以用 VCR gem。
@wcc526 哦,知道你碰到的问题了,你用的默认 TurboLinks 吧。这种情况你应该把所有的函数放到一个函数下 面,比如 init(), 然后
$ ->
init()
TurbolinkPageTransitionEventWhichIForgetExactMethod ->
init()
原因是你在 TurboLink 下面转页面时没有 document ready 这个事件,所以你之前写的函数不起作用。
具体 TurboLink event 用法你可以查文档,我好久没用不记得了
Best practice 就是,除非你指定页面的 Javascript 文件非常非常大,否则都放在 application.js 里面一起打包。
指定页面如果要加大库,比如 Google map, D3 之类,可以用异步载入。其他自有文件都可以在打包里面。
至于函数名冲突,那是你写 JS 的问题。应该改进写法,不能用改变载入的方法解决。
如果你实在要区分页面载入,可以这么写
<%= javascript_tag "foo.js" if controller.name == 'foo' && action == 'index' %>
很难看就是。而且 performance 一般只有轻微劣势,没有优势。
这个从逻辑上来说也不难。试一下吧。
首先建一个新 model, ContiniousLogin, 对应表 continious_logins。或者放在 yml 里面
然后做一个 rake task 或者 job
User.find_each do |user|
last_login_day = nil
days_count = 0
Login.find_each(name: user.name) do |login|
current_day = created_at.to_date
last_login_day ||= current_day
prev_day = current_day.prev_day
if prev_day == last_login_day
last_login_date = current_date
days_count += 1
elsif prev_day > last_login_day && days_count > 0
ContiniousLogin.create!(name: name, last_login_day: last_login_day, days_count: days_count)
last_login_day = nil
days_count = 0
end
end
end
逻辑大致如此,代码只做参考 :)
find_each 是每一千个一批次的,也可以调整批次大小,所以数据多少应该影响不大。当然如果时间太长可能就要另说了。
做实验时可以不用新建 model,用一个 yml 代替也行。总之有个 io 来存记录就好了。
我没有研究这部分的代码,但我对创建 test db 时要读取 development db 的内容表示质疑。应该是读取 schema.rb 就可以了。如果都要读取 development db 那 CI server 就没法跑了。
能给个理由 development db 为什么非要在远程吗?
当还有一堆 migrations 还在维护的时候,这个 gem 看起来很清爽。每个 model 的演化进程都很清楚。
但是有几个问题:
rollback 和 migrate 能否正常运行?这里没有测试来保证。
按时间戳的维护变困难了。就像@leozwa 和 @rainchen 说的,定期清理完全不需要的 migrations 也是 Rails good practices 之一。但现在 migration 不按时间排列,很难决定哪一截是需要和不需要的。
我提供两个思路来解决#2
思路一:提供一个 rake task 来按时间戳排列。但文件多可能很耗时间,且看不到文件细节。
思路二:完全放弃这个 gem 而采取一种新的思路。 这个 gem 的是按 model 或 namespace 查看。那么,直接做一个 rake task 是不是也能达到同样目的呢?
比如这些假想的 tasks:
rake migration list Post
这个就会列出所有 posts table migrations 文件。
rake migration view Post
这个就把所有 posts migrations 输出到 stdout 来观看。
这样的话,migration 还是不动,但多了些手段来方便查看,达到类似这个 gem 的目的。
• 明白自动测试比手动测试要好。
• 明白手动测试比自动测试要好。
到底你觉得哪个好啊
@lgn21st 明白了,多谢!
@huacnlee 不是的。貌似楼主以前是用的 Python 图标做头像所以一楼才说的。
话说@xiongxin8802 的建议也太烂了,难道 Ruby 社区就要人人用珠宝头像?
那就用一个子域名来放静态,不带 ssl 的。怎么样?
用 CDN? 靠谱不?
楼主放轻松,那两个帖子内容确实是少了点。爱社区就多放点干货啊。
@chenge Hash.new {|h,k| h[k] = [] }
返回的值虽然也是{}
, 但这个设计可以保证每一个不存在的 key 都会返回一个空 array, 而不是 nil
h = Hash.new {|h,k| h[k] = [] }
#=> {}
a = {}
#= {}
h == a
#=> true
# 下面差别出来了
h["foo"]
#=> []
a["foo"]
#=> nil
edit 和 new 难道不是同一份 partial?为什么会有区别?
@ywjno 你把数据库和 API 看成同样的东西就好了啊。MongoLab, 还有 Heroku 里面那些 MongoDB 的服务不都是 API 的形式?
@wcc526 就像你说的,确实不合理。应用是应用,数据是数据,两者不能混在一起。如果是 assets 图片,那么也是应用的一部分,可以在一起。如果是数据类型的图片,那就不太合适。
这个情况,如果是图简便的话,也可以这么做: