bin/rails runner path/to/script.rb
这个方法对 local storage 不太友好,用这个方法:
Rails.application.routes.url_helpers.rails_blob_path(user.avatar, only_path: true)
https://guides.rubyonrails.org/active_storage_overview.html#linking-to-files
这个对 Web 的看法比较狭隘,一方面,没有认识到 Web 是目前最流行的开放平台:
另一方面,夸大了大数据、AI 的应用场景,AI 跟 Web 不是竞争关系。只有少数应用像 Google 搜索那样以大数据和 AI 为核心竞争力,大部分场景只能用数据和 AI 改良部分的功能——例如让广告投放更准确、风控更可靠。下一个以 AI 为核心竞争力的领域可能是自动驾驶,但是所有人都要去做自动驾驶吗?一窝蜂的投入大数据和 AI 领域,小心以后工作就是当个财务报表分析员。
我维护过一个面向全球客户的关键后台服务,以 Mobile App 为终端,不提供 Web 界面,一样基于 Rails 开发。一个后台服务需要数据库、鉴权、序列化、后台任务等等功能,用 Ruby 还是用 Go 没有什么不同,难点不在语言而在业务。
马云是个商人、老板,听老板讲话不要说什么就是什么,而是分析背后的目的,难道有了 AI 就要基于 AI 重写淘宝?大家都搞 AI 去就不用跟淘宝在电商领域竞争了。
最后推荐一篇文章:Betting on the Web https://joreteg.com/blog/betting-on-the-web
Docker
要额外处理 PATH 问题。
估计是那几个 gem 导致错误捕捉除了问题:
group :test do
gem 'rails-controller-testing', '1.0.2'
gem 'minitest-reporters', '1.1.14'
gem 'guard', '2.13.0'
gem 'guard-minitest', '2.4.4'
end
我看了下这本书只说了替换 Gemfile 没说更换这些 gem 的理由是什么,对初学者很不利。
我推荐用《Rails 5 敏捷开发》这本书 https://book.douban.com/subject/27615703/
贴代码和运行结果。
一个 test case 是指一个 test "..." do end
块,可以随意自己添加。
错误打出异常栈是正常的,不然不好 debug,应该是书缺少提示了。
在同一个 test case 里面,遇到 error 或者 fail 之后,后面的代码就不执行了,因为很可能也会失败,没必要执行下去。test case 之间是独立的。
路由未定义。
errors 打出错误栈是正确的,书里有没有写“以下省略部分输出”?
说 docker 的说说用什么编排工具啊,总不能一台台上去操作吧。
创建目录、链接文件、运行迁移、重启进程,这些工作总要有工具做啊。
cap 就是个远程执行工具。
我用 cap 部署,systemd 监视进程。
写第三次再提炼。
云端的部署架构是什么?
如果是典型的 nginx 跟 app 在同一服务器,要把 nginx 的 root 指向 public 目录;如果是 heroku,则需要设置 RAILS_SERVE_STATIC_FILES 环境变量让 rails 进程处理静态文件,但这通常会在前面加一层 CDN。
…你先买本入门书把例子做完。
API 控制器收到的数据存到模型层,后台控制器再从模型层查数据。
用 validates 比较容易收集错误信息,而且不用访问数据库。
数据库异常不好处理错误信息,而且耗费了网络请求。
不承认对象客观存在,又变着法子模仿对象的功能,只能说开心就好。
你满嘴跑火车偶尔说对一两句话不出奇,我点赞对事不对人。看我博客发布日期,你确定不是看过我博客后记了下来?
Ops, 我忘了 elixir 相对 erlang 的改变之一就是增加了可重复绑定的变量,这在 erlang 认为是不纯。
直接修改实例变量,不比新增一个 struct 然后覆盖它更直观吗?
order.status = 'paid'
不懂你的观点。
Struct 用来约束数据结构,数据一旦生成就不可变,要改变的时候只能新增一个数据。例如:
defmodule Order do
defstruct number: '', status: 'open'
end
iex> order = %Order{ number: '20180101' }
%Order{number: '20180101', status: 'open'}
iex> order_paid = %{order | status: 'paid'}
%Order{number: '20180101', status: 'paid'}
iex> order
%Order{number: '20180101', status: 'open'} # 旧的数据依然存在
此时内存中存在两份 number 为 20180101 的订单,就因为 elixir 的变量不可变,新变量只是在假装不知道旧数据存在罢了。我认为这不是很好的对现实关系的映射。
用脚可以拿筷子吗?练练也是可以用的,但是有手的情况下何须用脚拿筷子。
无状态在处理数据流的时候也许有不少优点,但在跟 DB 交互这里,DB 作为数据流终点就是有状态的,强用无状态实现不是一个优势。
看了下文档,ChangeSet 不就是 Elixir 这样的函数式语言没有实例变量而不得不把所有变量通过参数传递么。
而且用起来跟 ActiveRecord 没啥区别:
changeset = User.changeset(%User{}, %{age: 0, email: "[email protected]"})
{:error, changeset} = Repo.insert(changeset)
changeset.errors #=> [age: {"is invalid", []}, name: {"can't be blank", []}]
user = User.new(age: 0, email: "[email protected]")
user.save
user.errors #= > <#ActiveModel::Errors ... @message={:age=>["is invalid"], :name=>["cant be blank"]}
看 Ruby 还短一点。
ChangeSet 用作 validation 一个坏处是很容易被跳过,不能当作数据入库前的守门人。用作 filter 还比较合理。Ruby 2.5 的 yield_self
就可以方便写出链式过滤器调用了。 https://blog.bigbinary.com/2017/12/12/ruby-2-5-added-yield_self.html 下一版也许会把 yield_self
增加一个 alias then
。
学习新语言看到新特性,就感觉无所不能,忘了以前是怎么做的,这是一种通病。函数式语言推广者把“无状态”奉为金科玉律,无视现实世界还有很多有状态的事物,成也于此败也于此。
不改。对接过 Web、Android、iOS、C++,设请求头都没有问题。说困难是他们忽悠你。
十楼方法是增加一个过滤器判断额外的 token,不改变 devise 内部,原理一样但更安全。