Rails 不知道这么做有没有什么问题?

nightire · 2013年01月19日 · 最后由 Rei 回复于 2013年01月20日 · 2949 次阅读

我正在做的一个应用,允许用户注册时填写用户名电子邮件,并且登录时可以任选一个。因为以前没做个这样的事情,所以我自己想了一下这样来实现了:

  1. 登陆表单给一个 input,用户填写用户名电子邮件都可以(二选一)

  2. 取值以后使用以下方法取得用户:

# identifier 是从表单里获得的值
def self.find_by_identifier(identifier)
  where('username = ? OR usermail = ?', identifier, identifier).first
end
  1. 然后去验证密码是否匹配

目前这么做可以,但是我发现这样取出来的用户不是一个 object,而是一个 array,获得的 user object 在这个 array 当中,得再用 first 把它取出来。我想这是因为我的查询条件里是 OR 的缘故吧?

我仔细考虑了一下,应该不会出现查询错误(新手程序员,缺乏经验),但是我不知道这样做是否是最好的方式,总觉得返回一个数组(尽管只有一项在数组里)怪怪的……大家觉得呢?有什么更好的方式教一下我呢?

没什么问题,where 本来,就是返回 数组

#1 楼 @hysios 哦,原来如此啊,我还没想到这一点,倒是我过分纠结了。

先判断一下 identifier 是什么类型 再根据类型来查找不会更好吗?

if email, find by email; else find by username

#4 楼 @gonglexin 嗯,你说得对,正有此打算。我是先实现,然后去重构,重构时我会采取你的建议,谢谢。

楼主可以加个 limit 1 进去 增加 db 性能 或是直接用 find 方法实现,不仅自动加了 limit 1,也不会再返回数组了

#6 楼 @iBachue 哦?以前一直用 where,还不知道这一点,我去看看 guide 吧,非常感谢!

#7 楼 @nightire 没用过 Rails 2 吧。find 才是正统。。where 是后来新出来的 不过确实比 find 好用

话说我当年也做过同样的功能 不过我是判断字符串中是否存在@的,存在就是 email 不存在就是 name

#8 楼 @iBachue 是的,新手,直接从 rails3 开始的,对 find 了解很少。你这么一说,我就想去仔细看看文档了。

#9 楼 @iBachue 那你这样还得做一个 validation,确保用户名不接受 @ 字符吧?

#10 楼 @nightire 呵呵 我也是新手 比你老一点 也是从 Rails 3 起步的 实习的时候也是用 3 可惜工作后就从 3 退到 2 了。。

#11 楼 @nightire 恩 是啊 用户名只能是由字母数字下划线之类的构成

我前不久也遇到,也用了最简单的方法,帮看看有木有问题 user = User.find_by_name(params[:session][:name]) || User.find_by_email(params[:session][:email].to_s.downcase)

当然存储是加了验证的,规则如下,正好避免某 email 和某用户名冲突 VALID_NAME_REGEX = /^(?!)(?!.*?$)[a-zA-Z0-9_\u4e00-\u9fa5]{1,50}$/ VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i

devise 的 wiki 里有提到思路,你可以借鉴 但不一定用 devise 其实关键思路就是你这样 @iBachue 我印象里是不需要自己加 limit 的 rails3 的 query chain 遇到 first 的时候 会自动加上 limit 1

username 和 usermail 做好校验,非空,username 不能含有 @,email 一定要含有 @,防止两个字段冲突。

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