第一本的发布日期就是 Mar 16, 2010,这还是发布时间,编写时间可能更早
Ruby 跨了大版本的书对新人来说除了添乱,几乎一点帮助都没有
@ad583255925 请告诉我 对方是不是 java
9 年前写的书还发 这不是坑人么 @huacnlee
看了下源码,如果没有 undef_method :name
就如你说的,会在第一调用的时候生成各种方法追加到 User 的实例方法中去,这个时候你调用 user.name
是不会触发 method_missing 的
现在来说你 undef_method :name
的情况,首先它会落入下面的 method_missing 方法中
# lib/active_model/attribute_methods.rb:425
def method_missing(method, *args, &block)
if respond_to_without_attributes?(method, true) # => 这里是 false
super
else
match = matched_attribute_method(method.to_s)
#<struct ActiveModel::AttributeMethods::ClassMethods::AttributeMethodMatcher::AttributeMethodMatch target="attribute", attr_name="name", method_name="name">
match ? attribute_missing(match, *args, &block) : super
end
end
def attribute_missing(match, *args, &block)
__send__(match.target, match.attr_name, *args, &block)
# match.target => "attribute", 这里调用了自身的 attribute 方法
end
# lib/active_record/attribute_methods/read.rb:76
def _read_attribute(attr_name) # :nodoc:
@attributes.fetch_value(attr_name.to_s) { |n| yield n if block_given? }
end
alias :attribute :_read_attribute
private :attribute
这下明白了吧
没去看源码 做了个小实验
class User < ActiveRecord
end
User.instance_methods.include?(:name) #=> false
user = User.new
User.instance_methods.include?(:name) #=> true
user[:name] = 'admin'
User.class_eval %q{undef_method :name}
User.instance_methods.include?(:name) #=> false
user.methods.include?(:name) #=> false
user.name #=> "admin"
看上去 attributes 的 methods 是懒加载的,只有在调用相关内容的时候才添加到 Class 里面,而且就算你把它从类里面 undef 掉,当你在实例上调用它时,它依旧会通过 method_missing 的 fallback 表现出正常的行为,应该算一种安全机制吧
最粗暴的 在 nginx 代理转发的时候改
另外给路由指定 format: :json 能应对你们的情况么
nginx 的 root 目录应该指向 public 而不是根目录
原则上 app 目录下的资源是不允许直接被 nginx 访问的,不需要 assets pipeline 管理的静态文件应该直接放到 public 目录下面去
不 include UserAddon 看看 User.methods 里面有没有 name 和 name=
# How many worker processes to run. Typically this is set to
# to the number of available cores.
#
# The default is "0".
#
# workers 2
puma 自己对 worker 这个参数的解释,你每 new 一个 Rails 项目都能看到这段话
另外你的 puma 配置里面,你只有一个核,开 3 个 worker 也没什么用,线程锁定 6 个也没什么意义,平时访问量很低的话 1, 6
应该会更合理
吐个槽:问题可以改成 Rails 应用如何正确的部署 production,并发量问题对它而言太笼统了
怎么会 压测显示 fonts.googleapi.com 明明很快的很稳定呀
@early 已经给出正确答案了
另外在补充一下,Rails 编译静态资源的时候,默认就生成了 gzip(.gz)格式的文件,所以对 assets 下的资源 Nginx 可以启用
gzip_static on;
application.js 的平均响应时间 4s 最高 9s, 你直接把 js 请求交给 Rails 处理了么?
生产环境要 assets:precompile
预编译,然后用 nginx 托管静态文件
压测做了没,现在能到多少?
没有场景谈优化都是散吹,按你目前的机器,不换语言的情况下,干掉 Rails 只用 Rack 应该还能提升一些,but 你愿意么
https://www.rubydoc.info/gems/watir/Watir%2FBrowser.start
start 就是 new + goto 吧,你是不是少写了 headless,所以 chrome 启动失败了
Watir::Browser.start url, :chrome, headless: true
第一个问题是因为 homeland 使用了 turbolinks,页面切换时浏览器是没有刷新的,你目前的写法『那段 js 代码』只会在浏览器刷新时加载,所以你需要在适当时候手动触发一下 js 的动作
老问题了,论坛里能搜到很多教程的
虽然最近在写 vue,但还是喜欢 erb + turbolinks 一把梭
向下兼容并不总是能解决所有问题,出了这个特性你用不用,一个项目里有的人用有的人不用,大丈夫?
很早就自建 es 了
并没有觉得有很大的必要
楼上的两位,这个问题可能已经被问及无数次了,也回答过无数次了
可以先试看么 哈哈哈~~~ 也许会考虑
歪个楼:从头开始学一个东西时,我还是习惯先买一本纸质书
为什么是 rails runner?不用 rake 么
User === User.first
# => true
User === User
# => false
Ruby 的 === 不是恒等,而是验证归属性的
避免 sql 查询只是 inverse_of 的作用之一,它更重要的意义是保证上下文中 post 实例是同一个对象,如果它在某处被修改了,不会与 post 的另一份实例形成竞争关系
微服务 这个概念本身我倒是觉得没什么黑的,我比较在意的是把 微服务 和 敏捷 放在一起的场景
网络辅导怎么想都不靠谱,有问题你可以论坛上发帖问,或者在 Ruby 的基友群里面问就好了
工作上最好的学习途径还是虚心跟着身边的高手学,因为有足够的时间呆在一起,比去买什么视频教程都有效多了
完全的统一编码风格是不可能的,这辈子都不可能的,rubocop 或者 codeclimate 约束一下就挺好了
关于第二点,你表述得略微有些极端了,有点一刀切的感觉。你们遇到的问题是系统设计带来的问题,也是大多系统都会遇到的,解决方式其实有很多
最简单的,写更新代码前,先跟对方沟通一下,或者结队编程,最起码 code review 一下
其次,使用 validate/callback 就能简单处理掉的场景,还是先考虑把 B 模型写得更健壮些吧
最后,就是你说的通过接口/消息去更新了,在避免犯错上确实很有效,相应的就是成本高了些