https://ruby-china.org/topics/31956 https://ruby-china.org/topics/32024 他写了两篇文章,可以先看一下。 不过,重构首先要技术过关,你自己也觉得 ruby 水平一般,就尽量先别动。能跑的代码总比出问题的代码好。哈哈。
书写规范,如果返回到是布尔,就用问号
吱,好久没参加聚会了。
如果一定要想实现在自己的服务器上登录微信的话,看下面这个。 Python 版 WeixinBot,基于微信 Web 的 API,我们是用 Ruby 重写了发送消息的功能。其他的自己写也能搞定。
哈哈,我想写到退休...
买一本支持一下。
其实,你可以看一下 Ruby China 的源代码,它就是用的 Elasticsearch,看看它怎么用的 Elasticsearch,在 Model 里做了什么,Gemfile 里用了那几个 gem 就知道了。再看看官方的文档就知道了。
这个好,
刚进公司时,负责将代码从 Rails 3 升级到 Rails 4,但是他们之前只写了一小部分。于是我重新补写了所有 Model,Controller 的测试(以前其实我也不写测试,之前的公司太 “敏捷” )
但写了之后,我有下面几个感觉
#2 楼 @zztczcx 这个帖子已经讲了,ActiveRecord 中的 Callback 浅析
实际上, if: :password_required?
的 if
option 特性,并不是来做ActiveModel
而是来自 ActiveSupport::Callbacks。之前好像有一个帖子专门讨论callback
的。
我把整个定义这个 validate 过程写下来,以Rails 5
代码为例,你就能看到在哪里执行 if 了。
validates
的定义 code
注意这段代码,validates_with(validator, defaults.merge(_parse_validates_options(options)))
validates_with
的定义在这里 code
然后有看到了,validate(validator, options)
validate
的定义在这里 code
首先看到这里,好激动,看到了if
if options.key?(:on)
options = options.dup
options[:if] = Array(options[:if])
options[:if].unshift ->(o) {
!(Array(options[:on]) & Array(o.validation_context)).empty?
}
end
同时下面还有一段 set_callback(:validate, *args, &block)
我们的if
还在 args
里面
到这里大概明白,实际上 validate 就是一个 callback
set_callback
是什么鬼?网上找会看到这段代码
included do
extend ActiveModel::Naming
extend ActiveModel::Callbacks #这个!!这个!!
extend ActiveModel::Translation
然后找到了ActiveModel::Callback
定义的地方。code,但是,实际上这里并没有做什么。
然后又看到了,
def self.extended(base) #:nodoc:
base.class_eval do
include ActiveSupport::Callbacks
end
end
ActiveSupport::Callbacks
,我们找到的是set_callback
的定义定义在这里code
其中有这段代码
mapped = filters.map do |filter|
Callback.build(self_chain, filter, type, options)
end
然后要找的就是Callback
的定义了
Callback
code
又一次兴奋的看到了if
def initialize(name, filter, kind, options, chain_config)
@chain_config = chain_config
@name = name
@kind = kind
@filter = filter
@key = compute_identifier filter
@if = Array(options[:if]) # 这个!!这个!!
@unless = Array(options[:unless])
end
接下来的问题,其实就比较轻松了,这和Callback
被执行时的,@if
是如何处理的。
在当前的页面,还能看到这段代码
def conditions_lambdas
@if.map { |c| CallTemplate.build(c, self).make_lambda } +
@unless.map { |c| CallTemplate.build(c, self).inverted_lambda }
end
这里,整个 @if Array
转化成了一个由 CallTemplate.build(c, self).make_lambda
组成的Array
,里面是什么呢?是lambda
。
conditions_lambdas
返回的 Array
去了哪里。我们还是在同一个文件里code
def apply(callback_sequence)
user_conditions = conditions_lambdas
user_callback = CallTemplate.build(@filter, self)
case kind
when :before
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter)
when :after
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
when :around
callback_sequence.around(user_callback, user_conditions)
end
end
这里其实有涉及到了,ActiveSupport::Callbacks
的执行逻辑,就不再深入,直接跳到最终执行的地方,还是同一个文件code
def skip?(arg)
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
end
这里有[email protected]_conditions.all? { |c| c.call(arg.target, arg.value) }
因为这是一个 Array
Enumerable .all?
的定义。code
all? [{ |obj| block } ] → true or false
Passes each element of the collection to the given block. The method returns true if the block never returns false or nil. If the block is not given, Ruby adds an implicit block of { |obj| obj } which will cause all? to return true when none of the collection members are false or nil.
if options
实际上是在这里执行的。#4 楼 @miserytan @first_dow
和 @last_dow
是为了存放你的结果,避免重复计算。
when 1 怎么不理解?
这个算法其实你可以自己去实现的。
补充一下,为什么要用上面的算法,是为了过滤你在 Settings.start_of_week
中设置 1-7 以外的数字。你也可以用别的算法。
支持
代码格式有点问题,多复制了一个 end 你理解的是对的 first_wday 返回的是一周的第一天是哪一天 last_wday 返回的是一周的最后一天是哪一天
为什么开始都是星期日?
因为这段代码 Setting.start_of_week.to_i
返回的是 7, 也就是默认设置的就是星期日是第一天,
如果你希望是星期一是第一天,那么 Settings.start_of_week
应该改成 1
select_tag
和 f.select
是不同的。
你看一下这两个函数参数的区别。
你这里其实有两个问题,
f.select
时不工作但是能够提交。我给几个提示
f.select
和 select_tag
生成的 HTML 代码有什么不同,它们具体是怎么用的。刷新页面不就是重新请求吗?!当然会执行 action 啊。
哈哈哈,两斤花椒吃了 3 年
你用错了find_by
看链接
#4 楼 @lehug 贴一下具体的代码吧 在用一下他贴的@u1440247613 网站,http://js2.coffee/ 看翻译出来的 JavaScript 是不是正确的。
首先,(this)
不是普通 JS 的用法,是带 jQuery 库的 JS。
所以如果你引入了 jQuery 库,在 CoffeeScript 中依然可以这么用$(this)
,没有问题,如果不行就要查一下其他原因了。
如果是纯 JavaScript,参见Element.getAttribute(attrName)