这明明是代码没写好 单行超过 120 个字符了吧
上周才开始写的代码 很高效啊
你在 create 里面 render 了 new.html.erb ,这个 template 需要 @customers
, 但是你的 create 方法里并没有提供这个变量,所以报了 NilClass
def create
@orderinfo = Orderinfo.new(orderinfo_params)
respond_to do |format|
if @orderinfo.save
format.html { redirect_to @orderinfo, notice: 'Orderinfo was successfully created.' }
format.json { render :show, status: :created, location: @orderinfo }
else
@customers = Customer.all # 提供 @customers 给 new.html.erb
format.html { render :new }
format.json { render json: @orderinfo.errors, status: :unprocessable_entity }
end
end
end
去掉关联就能保存是因为 belongs_to 会要求 presence validated ,如果 customer 并不是必须的可以指定 belongs_to :customer, optional: true
为什么有这样的结论?函数名就是变量啊
他们直接抛弃了 RESTful
应该是业务目前还够简单, controller 还没成长为裹脚布
这不只是 Rails 的问题吧,现在的『全栈框架』部署起来差不多都这个样子,毕竟涉及的东西就有这么多
其实也没有多复杂,只是楼主可能没有仔细去看 Rails 部署相关的文章,走了很多弯路
社区缺一篇相关的 Wiki 倒是真的
第一本的发布日期就是 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 一把梭