从rails 3中的另一个控制器调用模型中的方法

时间:2013-08-09 05:32:57

标签: ruby-on-rails ruby

在我的rails应用程序中,我需要调用另一个控制器在一个表中定义的方法。有两个表名为坐标和推文。推文表的条件由坐标表决定。在我的最终视图中,我需要显示tweets表的属性,其条件由坐标表决定。 我的坐标表代码

  class Coordinates<ActiveRecord::Base
      def self.query()
        a = Coordinates.where("city=?", params[:show])
        b = a.first
        if a.count == 1
          latitude = b.latitude
          longitude= b.longitude
          if(latitude=0 && longitude=0) then
            return  sql="Select * from tweets where tweet_text LIKE '%text%' AND user_loc LIKE '%show%' order by id desc"
          else if (latitude!=0 && longitude!=0) 
                 min_lat = latitude - 1.0
                 max_lat = latitude + 1.0
                 min_lng = longitude - 1.0
                 max_lng = longitude + 1.0
                 return   sql = "Select * from tweets where tweet_text LIKE '%text%' AND ( ((longitude BETWEEN min_lng and max_lng) AND (latitude BETWEEN min_lat and max_lat)) OR (user_loc LIKE '%show%') ) order by id desc"
               else
                 return   sql="Select * from  tweets where tweet_text LIKE  '%text%'"
               end    
          end
        end

我的推文表

class Tweets<ActiveRecord::Base
  attr_accessible  :id, :tweet_created_at, :tweet_id, :tweet_text, :tweet_source, :user_id, :user_name, :user_sc_name, :user_loc, :user_img, :longitude, :latitude, :place, :country

end

我需要从tweets_controller调用查询定义,以便它决定从tweets表中获取哪些查询并在最终视图中显示。但是params函数在model.rb文件中不起作用。我想要这样的东西 我的tweets_controller.rb

class TweetsController<ApplicationController
  def index
    Coordinates.query()
  end
end

我的最终观看代码

<%= @tweets.each do |tweets| %>

<ul>

  <li><%= tweets.id %></li>
  <li><%= tweets.tweet_created_at %></li>

  <li><%= tweets.tweet_source %></li>
  <li><%= tweets.tweet_text %></li>
  <li><%= tweets.user_id %></li>
  <li><%= tweets.user_name %></li>
  <li><%= tweets.user_sc_name %></li>
<li><%= tweets.user_loc %></li>
  <li><%= tweets.user_img %></li>
  <li><%= tweets.longitude %></li>
  <li><%= tweets.latitude %></li>
<li><%= tweets.place %></li>
  <li><%= tweets.country %></li>

</ul>
<% end %>

我无法从tweetscontroller调用坐标表中定义的查询函数。我也尝试使用辅助方法,但这似乎没有帮助,听起来很复杂。有人帮我这个

3 个答案:

答案 0 :(得分:3)

实际上,我发现您的代码存在一些问题。

首先:使用有意义的名字。您正在检索与某个城市相关的推文。其次,在您的query方法中,您尝试执行的大多数操作都是检索推文,这些推文应该在推文模型中。

你的代码错误:

  • 它只是构建了sql?
  • 搜索包含固定文本%text%的推文,我假设应该是一个给定的搜索词
  • 它搜索给定的用户位置%show%,我假设应该是城市名称(您的params[:show]

我建议:

  • 查找推文应该在Tweet模型
  • 使用更小的方法
  • 为简单起见,我假设您的搜索字词为params[:text]

所以我会按如下方式编写代码:

class TweetsController < ApplicationController

  def index
    city = params[:show]
    search_term = params[:text]
    city_coordinates = Coordinates.where('city=?', city)
    @tweets = if city_coordinates.count == 1 && city_coordinates.first.valid_location?
                Tweet.for_coordinate(city_coordinates.first)
              else
                Tweet.for_user_location(city)
              end
    @tweets = @tweets.where("tweet_text like ?", "%#{search_term}%")
  end
end

不要自己构建sql,让activerecord为你做这件事。另外:where是懒惰的,因此您可以轻松链接它们。

然后在您的Coordinate模型中添加

class Coordinate < ActiveRecord::Base

  def valid_location?
    self.latitude != 0 && self.longitude != 0
  end

end

并在您的Tweet模型中

class Tweet  < ActiveRecord::Base

  def self.for_coordinate(coordinate)
    bbox = { min_lat: coordinate.latitude - 1.0, max_lat: coordinate.latitude + 1.0,
             min_lng: coordinate.latitude - 1.0, max_lng: coordinate.latitude + 1.0
           }
    Tweet.where("(longitude BETWEEN ? and ?) AND (latitude BETWEEN ? and ?)) OR (user_loc LIKE ?)", 
       bbox[:min_lng], bbox[:max_lng], bbox[:min_lat], bbox[:max_lat], "%#{coordinate.city}%")

  end

  def self.for_user_location(city)
    Tweet.where("user_loc like ?", "%#{city}%")  
  end

end        

答案 1 :(得分:2)

在模型中的self.query方法中,设置如下参数:

class Coordinates<ActiveRecord::Base

      def self.query(something)
        a = Coordinates.where("city=?", something)
        b = a.first
        if a.count == 1
          latitude = b.latitude
          longitude= b.longitude
          if(latitude=0 && longitude=0) then
            return  sql="Select * from tweets where tweet_text LIKE '%text%' AND user_loc LIKE '%show%' order by id desc"
          else if (latitude!=0 && longitude!=0) 
                 min_lat = latitude - 1.0
                 max_lat = latitude + 1.0
                 min_lng = longitude - 1.0
                 max_lng = longitude + 1.0
                 return   sql = "Select * from tweets where tweet_text LIKE '%text%' AND ( ((longitude BETWEEN min_lng and max_lng) AND (latitude BETWEEN min_lat and max_lat)) OR (user_loc LIKE '%show%') ) order by id desc"
               else
                 return   sql="Select * from  tweets where tweet_text LIKE  '%text%'"
               end    
          end
        end

在您的控制器中,将params[:show]作为参数传递:

class TweetsController<ApplicationController
 def index
  @tweets = Coordinates.query(params[:show])
 end
end

现在它应该工作了。感谢

答案 2 :(得分:0)

您拨打Coordinates.query(),但实际上并未存储返回值。

试试这个:

@tweets = Coordinates.query()