2

尝试创建新的推文以显示在我的索引中,但我不想离开页面。我的应用程序所需的功能是跟踪来自推文流的推文,并自动将该信息传递到我的推文对象并保存到数据库。

控制器:

class TweetsController < ApplicationController

  TWITTER_COMSUMER_KEY = "GfqdzJKb5kIyEnYlQuNGlg"
  TWITTER_CONSUMER_SECRET = "A3Fe0IvDbhlKgowCVmV1WVLlcdYgQ8w9clrDSegCQ"
  TWITTER_OATH_TOKEN = "34012133-caUYq3eiNC7Z9L9KvTgG51VgyctqVxkXP0tKIXDk0"
  TWITTER_OATH_TOKEN_SECRET = "DSLA3F8BPssyEeEP2wZgQ1OJRL5kIVPZfON4GYZFw"

  TweetStream.configure do |config|
    config.consumer_key = TWITTER_COMSUMER_KEY
    config.consumer_secret = TWITTER_CONSUMER_SECRET
    config.oauth_token = TWITTER_OATH_TOKEN
    config.oauth_token_secret = TWITTER_OATH_TOKEN_SECRET
  end

  def index
    @tweets = Tweet.all
  end

  def new
    @tweet = Tweet.new
  end

  def create
    TweetStream.track('bed', 'morning', 'breakfast') do |status|

      temp = status.text
      if(temp.include? "http")
         @tweet = Tweet.new(status.text)
         if @tweet.save
         else
           render "new"
         end
      end
    end
  end

  def show

  end
end

索引.html.erb

<h1>Tweet Tracker</h1>

<% @tweets.each do |tweet| %>
    <p><%= tweet.content %></p>
    <hr />
<% end %>
4

2 回答 2

1

这是 RESTful 资源结构(索引/显示/创建/编辑/销毁)的一种有趣方法,因为我们使用自动跟踪器来创建而不是任何用户输入。问题是,您的控制器代码仅在通过 POST 请求访问时运行(除非您弄乱了 routes.rb 以使其响应其他内容)。

在我看来,最干净的解决方案是编写一个咖啡脚本来定期将数据发布到控制器并显示结果。

/app/assets/javascripts/tweets.js.coffee

$ ->
    setInterval ->
      $.post("/tweets", "", (html)->
            $("#tweets").append html)
     , 1000

/app/views/tweets/create.html.erb

<p><%= @tweet.content %></p>
<br/>

为了让它正常工作,我们需要将推文区域包装在一个 id="tweets" 的 div 中:

/app/views/tweets/index.html.erb

<h1>Tweet Tracker</h1>

<div id="tweets">
<% @tweets.each do |tweet| %>
   <p><%= tweet.content %></p>
   <br/>
<% end %>
</div>

您还需要render "new"在控制器的 create 方法中替换为return. 这样,当保存到数据库失败时,不会呈现任何内容,并且一切都会继续,没有错误。

于 2013-03-14T03:25:48.067 回答
1

你有两个重要的部分:

  • 监听流式 API 并创建对象
  • 在创建新对象时更新用户的视图

第二位可以通过一些简单的 javascript 轮询来完成,如@AustinMullins 的回答。

第一个位应该在控制器中完成 - 它们用于响应请求并且偏离那种工作可能最终导致意外行为或性能问题。

例如,我发现在 Phusion Passenger 上运行的站点上,服务器会创建一个线程来处理请求,然后如果它没有自行完成,则在一定时间后将其杀死,当然它不会如果控制器开始监听一个永无止境的输入流。

相反,您应该获得一个可以从命令行启动的单独脚本。这是一个类似于我正在使用的示例:

脚本/tracker.rb

#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= "production"
require File.dirname(__FILE__) + "/../config/environment"
TweetStream.configure do |config|
  config.consumer_key = TWITTER_COMSUMER_KEY
  config.consumer_secret = TWITTER_CONSUMER_SECRET
  config.oauth_token = TWITTER_OATH_TOKEN
  config.oauth_token_secret = TWITTER_OATH_TOKEN_SECRET
end

client = TweetStream::Client.new
client.track(*Keyword.pluck(:name)).each do |status|
  Tweet.create(status.text)
end

脚本/tracker_ctl

#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
Daemon.new('tracker.rb')

现在,您可以 ssh 进入您的服务器并运行script/tracker_ctl startor script/tracker_ctl stop。但是您可能想要做的是让控制器操作发出这些命令。

于 2013-03-14T05:48:04.660 回答