【问题标题】:Help constructing a complex DB query in rails帮助在 Rails 中构建复杂的数据库查询
【发布时间】:2011-06-07 04:11:49
【问题描述】:

我希望你们中的一些 sql 专家可以帮助我在 Rails 中构建一个相对复杂的(无论如何对我来说)查询。我有两个相关模型,一个 Story 模型和一个 Post 模型。

class Story < ActiveRecord::Base

attr_accessible :title

  belongs_to    :user
  has_many  :posts,
        :dependent  =>  :nullify


class Post < ActiveRecord::Base

  attr_accessible :contents

  belongs_to    :story, :touch => true
  belongs_to    :user, :touch => true

每个故事实例都充当多个帖子实例的包装器。我希望能够在数据库中搜索具有在特定时间范围内创建的帖子的故事,如果有一个故事在给定时间范围内创建了帖子,则返回所有故事属性以及在时间范围内创建的故事最近创建的帖子(也包括所有属性)。我可以获取故事属性和 post_id,但我不知道如何获取其余的帖子属性。

这是我在 Post.rb 中得到的:

  scope :within_user_preferred_date_range, lambda { |user| 
    where("posts.created_at BETWEEN ? AND ?", 
        (Time.now.midnight - user.preferences[:start_story_date_offset_in_days].days), 
        (Time.now - user.preferences[:end_story_date_offset_in_days].days )) } 

  ####################################

  def self.close_timely_posts(user) 
    Post.includes(:story).within_user_preferred_date_range(user).select("DISTINCT(story_id)")   
  end

这会生成以下 sql 查询,显然这不是我所需要的:

←[1m←[35mPost Load (0.0ms)←[0m  SELECT DISTINCT(story_id) FROM `posts` WHERE 
(posts.created_at BETWEEN '2011-06-03 07:00:00' AND
'2011-06-06 19:34:40') ORDER BY posts.created_at DESC
  ←[1m←[36mStory Load (0.0ms)←[0m  ←[1mSELECT `stories`.* FROM `stories` WHERE (`stories`.`id` IN (70,57,53,55,16,54,51,56,52,60,59,58))←[0m

如果您对此查询提供任何帮助,我们将不胜感激!

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-3 activerecord


    【解决方案1】:

    尝试将您的代码修改为:

      def self.close_timely_posts(user) 
        Post.includes(:story).within_user_preferred_date_range(user).select("DISTINCT(story_id), posts.*")   
      end
    

    【讨论】:

    • 嗯。按照您的建议导致以下错误消息:←[1m←[35mPost Load (0.0ms)←[0m SELECT DISTINCT(story_id), * FROM posts WHERE (posts.created_at BETWEEN '2011-06-04 07:00 :00' AND '2011-06-07 23:31:24') ORDER BY posts.created_at DESC Mysql2::Error: 你的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 '* FROM posts WHERE (posts.created_at BETWEEN '2011-06-04 07:00:00' AND '2011-0' 附近使用正确的语法: SELECT DISTINCT(story_id), * FROM posts WHERE (posts.created_at BETWEEN ...
    • [完成错误信息] ... '2011-06-04 07:00:00' AND '2011-06-07 23:31:24') ORDER BY posts.created_at DESC跨度>