新手问题 请教一个 ruby-china 论坛代码问题

boyishwei · 2013年12月18日 · 最后由 boyishwei 回复于 2013年12月18日 · 3018 次阅读

一边学,一边在做项目,前段时间把 ruby-china 的源码 clone 了一份到本地,用心的在研究,先谢谢论坛的大神哈,受益良多,谢过谢过 :)

今天看到一个小细节,没看懂,向大家请教一下: 论坛功能中,在每次回复后,都要去更新帖子的最后回复人以及最后回复时间: 在代码reply.rbtopic.rb

reply.rb中的代码段:

after_create :update_parent_topic
  def update_parent_topic
    topic.update_last_reply(self)
  end

topic.rb中的代码段:

def update_last_reply(reply)
    # replied_at 用于最新回复的排序,如果贴着创建时间在一个月以前,就不再往前面顶了
    self.last_active_mark = Time.now.to_i if self.created_at > 1.month.ago
    self.replied_at = Time.now
    self.last_reply_id = reply.id
    self.last_reply_user_id = reply.user_id
    self.last_reply_user_login = reply.user.try(:login) || nil
    self.save
  end

没想明白的问题就是:在 topic.rb 的 update_last_reply 中,self 是如何对应上 reply 的 topic 的,没有看到那里有对 self 有显示的指定啊,比如 self=reply.topic,难道这里也是一个 convention over configuration 的案例吗。

感觉好像是我学的时候漏了什么点没学到,问题可能很白痴,但就是没想明白,别见笑哈... :)

另外补充一个问题: 还有那些其他比较优秀的开源项目可以 clone 下来学习,参考一下的。经过一段时间学习跟实际开发之后,再观摩其他大神的 code 方式,应该是,至少我觉得,这个阶段帮助我提升最快的一种方式。从规划,代码风格,以及一些细节实现方式上,都有让人眼前一亮的感觉,比如看 ruby-china 的源码,就让我一路亮着。希望能观摩更多其它大神的佳作,如饥似渴啊...哈哈,论坛 wiki 里也有非常多的好东西哈,谢谢整理 wiki 的大神,,,:)

self 是 reply 的实例,不是 topic。在 reply.rb 中,self 就是 reply 自己,把自己的实例传递给了 topic 的那个方法,在那个方法里,用本地变量 reply 接收传过来的 self

这倒不是什么 convension,也不是你遗漏了什么。self 是谁,这是 OO 编程里的基本功,而方法传参则是编程的基本功。

猜想你的疑惑源自于你把第一段代码里的 self 当成了第二段代码里的 self,所以会想:“奇怪,没有显示声明 self = reply.topic 呀……”

然而,这两个 self 根本就是完全不一样的对象,第一段代码里的 self 等同于第二段代码里的 reply

#1 楼 @nightire 用本地变量 reply 接收传过来的 self,这个我理解了的,topic.rb中方法 update_last_reply 里的 self 是代表某一个 topic 实例吧,我是说这个 self 是怎么对上传过来的这个 reply 所回复的 topic 的 :)

#1 楼 @nightire 嗯嗯,问题就是topic.rb中的 self,他是怎么对上我所回复的 topic 实例的,,, :)

#3 楼 @boyishwei topic.update_last_reply,topic 不就是 update_last_reply 的 self 吗?

#3 楼 @boyishwei topic.update_last_reply(self) equivalents to self.topic.update_last_reply(self)

我觉得楼主不是不清楚 self,而是不清楚 update_last_reply 中 topic 和 reply 是怎么对应起来的。在这里并没有产生关联,因为 last reply 和其它 reply 一样,已经在它产生的时候和 topic 对应起来了,所以 reply.topic 已经是 self 了,这个函数的目的是拿到最后的一个回复,self.last_reply_id = reply.id 已经做到了

#6 楼 @nightire topic.update_last_reply(self)self.topic.update_last_reply(self)是相等的吗? 也就是说self.可写可不写.....?

self.topic.update_last_reply(self)这么写,那就非常明了。

比如reply.rb里还有其他代码:

def update_parent_topic_updated_at
  if not self.topic.blank?
    self.topic.touch
  end
end

这里就很很清楚,self.topic通过 self 中的 topic_id 字段关联出回复的 topic.

topic.update_last_reply(self)这里没显式的self.topic,就懵了,不知道这个topic从哪里来的..

#4 楼 @AlphaLiu 嗯嗯,这里理解了的

#5 楼 @reyesyang 之前也看过,温故而知新...:) #7 楼 @guyanbiao 嗯,大概是这个意思,不知道 topic 从那来...

#8 楼 @boyishwei 说来说去,还是因为你不知道第一段代码里的 topic 是怎么来的,如果你这么问就清楚多了。不过也的确建议你再深入理解一下 self 的各种特性。

#9 楼 @nightire 嗯嗯,:) 谢谢各位

需要 登录 后方可回复, 如果你还没有账号请 注册新账号