Homeland Ruby China,对!没错!...不好意思,报告个 Bug

Peter · 2012年07月16日 · 最后由 Rei 回复于 2012年07月16日 · 2722 次阅读

各位管理员 @lgn21st @huacnlee

首先谢谢你们做了这样一个系统, 给我们提供了一个好的学习样本。不过今天又发现个 bug, 或者说是上次报告的 bug 的衍生 bug

[Email 可以随便修改, 用户可以随便自杀, 不用提供密码](http://ruby-china.org/topics/4260), 这些事弱爆了, 用户自己头脑清醒点就没事了, 出问题可以推给用户, 因为他们自己没有登出, 被改 Email 也怪不得谁。

我接受现实了, 继续改用户系统, 今天我想让用户从 Facebook 进来第一件事就是改掉系统给他们设置的随机用户名 (login) 和 密码。所以我在 user 表加了个字段, 如果为 0 且用户不在修改用户名和密码的页面/account/edit, 我就重定向 (redirect_to) 过来, 代码写好了, 测试: /topics /wiki /sites 都可以跳回 /account/edit

开心。

但点 “会员” /users, 出现 404, 好吧, 自己技术不行, 那就接受现实, 到处 puts 吧, 总会找到哪出的问题。

夜深了, 我也挖得更深了, 最后找到这个文件: .rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.6/lib/action_controller/metal/redirecting.rb

def redirect_to(options = {}, response_status = {}) #:doc:
  raise ActionControllerError.new("Cannot redirect to nil!") unless options
  raise AbstractController::DoubleRenderError if response_body

  self.status        = _extract_redirect_to_status(options, response_status)
  self.location      = _compute_redirect_to_location(options)
  self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.h(location)}\">redirected</a>.</body></html>"
end

一顿 puts 之后, 发现只有/users 链接 self.location 为 nil, 我直接赋值也不行:

self.location      = "http://localhost:3000/account/edit"

好吧, 我想知道这个 location 是个什么东西, 在.rvm/gems/ruby-1.9.3-p194/gems/ 目录下 ack 一顿乱找, 无果。 中间修改了其他文件后有好些出错信息, copy+google 也无果。

因为修改 gemset 里面的文件要重启rails s, 时间就不知道浪费多少了, 终于在今天, 就在今天, 突然想到在 app/controller/users_controller.rb里面看看, 之前只关注过 UsersController 的 before_filter, 没有搜索过 location, 一搜发现, 果然有戏

  def location
    @location = Location.find_by_name(params[:id])
    if @location.blank?
      render_404
      return
    end
...
 end

原来 UsersController 自己有个 location 方法, redirect_to 函数里面想把一个链接字符串硬塞给 location, 人家怎么可能要, 人家又不傻, 只有我傻了。

把这段注释掉, 好了, 可以跳转了, 当然这只是发现问题, 解决问题要做事还很多呢。这个 location 还导致了官方网站还有另一个 Bug, 就是输入不在 location 表里的地名, 比如 “一个城市”, 就会去 404。

============================================================ 所以请管理员们或各路高手指导一下吧, 我觉得最好把 users 表里的 location 字段和这里的 location 方法最好改个名, 比如"hometown", rails 里面不至于用这种词吧。

我想来修补这个 bug, 不知道要修改些什么, 如果你们能指点一下, 不胜感激。

如果有高手想做, 那就再好不过了。

这里应该只需要把 location 这个 Action 换一个名字就好了。 赞楼主的深入挖掘的精神。 BTW. 不需要搞 Facebook 登陆,这里没法接入,服务器再国内,OAuth 连不上的。

首先感谢楼主报 bug,不过信息量太大我没提炼出要点是什么。到底是:

  1. 做了什么修改?
  2. 出了什么错误?

谢谢 @huacnlee 回复, 关于在 /account/edit 中填的城市如果不在 location 表中, 就会定位到 404 这个官方都存在的 bug 如何修复呢? app/controller/users_controller.rb

if @location.blank?
      render_404
      return
end

location 表中原来存在的城市应该也是大家填的吧, 这个 bug 是不是最近才出现的, 原来计划应该是检测 location 表中有没有用户输入的城市, 有的话直接在 users 表中加入 location_id, 没有的话在 location 表加入城市名称, 然后把该城市的 location_id 加入用户信息中。

@Rei 错误就是app/controller/users_controller.rb中有个def location, 但 rails 中会用到location这个字段, 这样当 rails 给self.location赋值的时候, 就会出错。

另外的 bug 就是在这个页面 http://ruby-china.org/account/edit 请在城市那输入 "九寨沟", 你看一下是不是到 404 去了?

@yzhrain 的经验:

命名时请留意 Rails 下的关键字 http://yangzhihuan.iteye.com/blog/577657

把 action 的名字改掉就行了。

@Rei 我现在没看代码, 难道改掉就可以了, 这个 action 没有地方用吗?

@huacnlee @Rei 4 楼"九寨沟"的问题应该怎么改, 指点一下, 担心涉及很多文件,改了留下后患, 谢谢

#7 楼 @Peter 还要改掉路由,把 /users/location 显式指到那个 action

match "users/location/:id", :to => "users#新action名", :as => :location_users

PS:这里应该用 get 不用 match,可以顺便改了

编码问题似乎是 moped 这个 gem 的问题,升到 1.0.1 解决。

bundle update moped

Peter 报告 Bug 中提及了此贴 04月03日 10:56
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册