使用 Sinatra 和 MongoDB 在 IBM Bluemix 上构建一个大会签到程序-4
 
- UID
- 1066743
|

使用 Sinatra 和 MongoDB 在 IBM Bluemix 上构建一个大会签到程序-4
第 6 步. 允许用户签到目前位置,我们的应用程序还只是一个只读应用程序。现在是时候为用户提供一种创建签到进入应用程序的途径了。首先,为签到表单页面创建一条路线。
1
2
3
4
5
6
| get '/checkin' do
# Get a list of locations for the dropdown
locations = settings.locations.find.sort(:name).to_a
haml :checkin, :locals => {:locations => locations, :error => params[:error]}
end
|
此路线很简单 — 它获取一个位置列表,并将该列表传递给 checkin.haml 视图。此视图向用户显示一个表单。它有两个字段:一个输入用户的 Twitter 用户名的文本框,一个包含可用位置的下拉列表。它使用我们从该路线传递的位置来填充。
该表单的 action 属性设置为 URL /checkin。在用户提交表单时,它会在一个 POST 请求中将数据传输到此 URL。为此,我们需要创建另一条路线。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| ...
post '/checkin' do
...
# Check if user has checked in before
checkin = settings.checkins.find_one(:twitter_username => username)
if(checkin)
# Update existing checkin
checkin['location_id'] = BSON::ObjectId(location_id)
checkin['timestamp'] = Time.now
settings.checkins.update({"_id" => checkin["_id"]}, checkin)
else
# Insert new checkin
checkin = {
:twitter_username => username,
...
:timestamp => Time.now
}
settings.checkins.insert(checkin)
end
# Get location details
location = settings.locations.find_one(:_id => BSON::ObjectId(location_id))
# Redirect to location page
redirect "/location/#{location['slug']}"
...
end
|
此代码将从表单中获取 Twitter 用户名和所选的位置,使用此信息让用户签到。它首先会在 Twitter 上找到该用户 — 如果用户不存在,那么它会返回一个错误并重定向回签到表单。然后,它会确定用户是否已签到。如果已签到,那么它会对数据库中的现有文档执行更新,但如果不是,那么它会插入一个新文档。
备注:如果考虑在外界部署一个这样的应用程序,则应该实现 Twitter 的 OAuth 身份验证,验证用户是否拥有他们用于签到的 Twitter 帐户。为了简便起见,本教程没有介绍此概念。
在更新数据库后,应用程序会将用户重定向到所选位置的位置页面,在该页面中,用户会看到他们的签到信息,以及其他任何已签到进入该位置的用户。
用户现在可签到进入任何位置了。您还会注意到,主页现在将在 Activity Stream 上显示来自所有位置的最新签到信息。应用程序的核心功能现已完成。作为补充,我们创建了 “Tweets” 页面,其中将会显示 10 条包含大会标签 #myconf2014 的最新的推文。
第 7 步. 查看包含大会标签的推文使用 Twitter API 相对简单一些,尤其在使用 Ruby 中的 twitter 工具时。但是,您需要注意的一点是,Twitter 对它的大多数 API 都有很低的速率限制 — 尤其是检索推文和用户信息的 API。为了避免超过这些限制,您需要仔细考虑实现 API 的战略。
在撰写本文时,搜索 API 的速率限制为每个经过验证的用户每小时 180 条请求(每个应用程序 450 条)。这个数字听起来可能比较合理,但想象一下,如果每次有人访问您的页面,您都需要发出一个 API 请求,那么您很快就会达到速率限制,达到该限制时,在 15 分钟之后您才能再次使用它。反复达到限制可能被加入黑名单,永远被拒绝使用该 API。
解决此问题的最佳方式是,将推文缓存在自己的数据库中,本示例中就是这么做的。无需每次用户访问 “Tweets” 页面时都查询该 API,我们会检查是否已经将推文缓存在数据库中。如果未缓存,或者上次缓存推文已超过 5 分钟,那么我们将会向该 API 请求新推文,并将这些推文保存到数据库中。
首先,在 app.rb 中需要一个新路线 /tweets。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| ...
get '/tweets' do
# Get one tweet from the database to check if we need to fetch new tweets
tweet = settings.tweets.find_one
tweet ? minutes = (Time.now - tweet['retrieved_at']).to_i / 60 : 0
if(!tweet || minutes > 5)
# Get new tweets
newTweets = settings.twitter.search("#myconf2014", :result_type => "recent").take(10).to_a
# Remove cached tweets from DB
settings.tweets.remove
newTweets.each do |t|
tweet = {
:twitter_username => t.user.screen_name,
...
:retrieved_at => Time.now
}
# Cache each tweet into DB
settings.tweets.insert(tweet)
end
# Reset minutes since last updated to zero
minutes = 0
end
# Get tweets from DB
tweets = settings.tweets.find.sort(:tweet_time => :desc).limit(10).to_a
haml :tweets, :locals => {:tweets => tweets, :updated => minutes}
end
|
此代码从数据库获取一条推文,并检查自获取该推文以来已经历了多少分钟。如果未找到推文或者已经过去了 5 分钟,那么它会在 Twitter 中搜索新推文,从数据库中清除旧推文,然后保存新推文。然后,它会从数据库中搜索 10 条最新的推文,并将它们传递给 tweets.haml 视图。此视图显示了自上次获取推文以来经历了多长时间,以及一个推文表。该模板将会迭代每条推文,显示用户的头像、屏幕名称、真实名称、推文文本,以及自发表该推文以来经历了多长时间。该页面看起来应类似于下图。
这个应用程序到现在就完成了。一定要使用下面这条命令将更改推送到 Bluemix:
恭喜您,您现在已经使用 Ruby、Sinatra、Haml、Bootstrap 和 MongoDB 构建了一个大会签到应用程序,并将它部署到了 IBM 的 Bluemix 平台上!
结束语刚创建的应用程序是一个完整的 Sinatra 应用程序,受 上的 MongoDB 服务支持。这是一个不错的起点,您还可以通过许多方式对它进行改进。对于初学者,您可以获取希望实现 Twitter 身份验证,要求用户在登录到 Twitter 之后才能签到。您还可以允许用户直接从应用程序发送推文,等等。IBM Bluemix 提供了多个服务来帮助您轻松扩展此应用程序 — 只有想不到的,没有做不到的。 |
|
|
|
|
|