如何使用续集在sinatra中获取这个ruby代码?

时间:2015-09-05 00:19:17

标签: ruby sinatra sequel

我试图只允许一个人看到该页面,如果他们的名字在数据库中。我认为最好的方法是循环遍历所有条目并检查它是否匹配,如果它然后显示它并停止循环。我一直在得到一个空白的页面,有什么帮助吗?

get '/' do
  user  = "john"
  num = DB[:users].all

  for person in num  do
    if person[:name].to_s == user then
      File.read('index.html')
      break
    else 
      "you're not authorized"
    end
  end

end

如果我要删除在if语句中显示break的行,我会收到此错误:

  NoMethodError at /
  undefined method `bytesize' for #<Hash:0x007fcf60970a68>
  file: utils.rb location: bytesize line: 369

1 个答案:

答案 0 :(得分:1)

问题是for循环评估为nil(除非您break并为break提供值),因此您的块正在返回{{1} ,所以没有什么可以渲染的。

但真正的问题是nil在这里是错误的解决方案。您要做的是检查数组for是否包含DB[:users].all成员等于:name的哈希。你可以使用循环,但除了user在惯用的Ruby代码中很少见(for是首选),它会使代码的意图更难理解。相反,您可以使用Enumerable#find(Array类包括Enumerable模块中的方法),如下所示:

Enumerable#each

...但是因为你实际上并不关心匹配的用户 - 你只关心匹配的用户是否存在 -it会更清楚地使用Enumerable#any?,这只会返回get '/' do username = "john" users = DB[:users].all matching_user = users.find do |user| user[:name] == user end if matching_user return File.read('index.html') end "you're not authorized" end true

false

编辑:正如@ user846250指出的那样,让数据库完成检查是否存在匹配用户的工作会更好。像这样:

get '/' do
  username = "john"
  users = DB[:users].all

  if users.any? {|user| user[:name] == user }
    return File.read('index.html')
  end

  "you're not authorized"
end

这是首选,因为不是将数据库中的所有记录都加载到Ruby(这是get '/' do username = "john" if DB[:users].where(:name => username).empty? return "you're not authorized" end File.read('index.html') end 将要做的事情) - 当你实际上并不关心其中任何一个数据时 - 续集只会询问数据库是否有任何匹配的记录,然后返回DB[:users].alltrue