2015-09-05 34 views
0

我想只允许一个人看到页面,如果他们的名字在数据库中。我想最好的方法是循环遍历所有条目并检查它是否匹配,如果它确实显示并停止循环。我一直得到一个空白页面,有任何帮助?我怎样才能得到这个ruby代码与续集在sinatra工作?

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 

如果我删除说,如果语句中打破了线,我得到这个错误:

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

你忘了发布你收到的错误。 –

+0

我得到的是一个空白页,我在尝试其他类似的事情时得到了错误,但是对于这个具体情况,我的页面是空白的,我无法弄清楚为什么,如果我拿出'break'我得到错误在它下面 –

回答

1

的问题是,一个for循环计算到nil(除非你break和供应一个值为break),所以你的块返回nil,所以没有什么可渲染的。

但真正的问题是for在这里是错误的解决方案。你要做的是检查数组DB[:users].all是否包含一个散列,其中的:name成员等于user。您可以使用循环,但除了惯用的Ruby代码中罕见的forEnumerable#each是首选)之外,它使代码的意图更难理解。相反,你可以使用Enumerable#find(Array类包括可枚举模块中的方法),像这样:

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 

...但因为你实际上并不关心匹配的用户,你只关心是否匹配用户存在 - 它会更清楚使用Enumerable#any?,刚刚返回truefalse

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 

编辑:作为@ user846250指出,这将是最好让数据B ase做检查是否存在任何匹配用户的工作。事情是这样的:

get '/' do 
    username = "john" 

    if DB[:users].where(:name => username).empty? 
    return "you're not authorized" 
    end 

    File.read('index.html') 
end 

这是可取的,因为不是从数据库到红宝石(这正是DB[:users].all会做)加载所有的记录 - 当你实际上并没有任何人关心数据--Sequel只会询问数据库是否有匹配记录,然后返回truefalse

+0

哇谢谢,我不知道在红宝石中是罕见的,我只是从基本的python过来。 –

+1

因为你使用'Sequel',你实际上可以使用更像SQL的查询,如'!DB [:users] .where(:name => username).empty?',如果用户存在,否则为'false'。 –

+0

好的,@ user846250。我已经编辑了我的答案,以包含这些信息。 –

相关问题