【问题标题】:Rails 3 find all associated records has_many :throughRails 3 找到所有关联的记录 has_many :through
【发布时间】:2011-02-17 10:19:52
【问题描述】:

我想列出与某个特定类别和课堂相关的所有帖子。

我有:

class Post < ActiveRecord::Base
  has_many :category_posts
  has_many :categories, :through => :category_posts
  has_many :classroom_posts
  has_many :classrooms, :through => :classroom_posts
end

class Category < ActiveRecord::Base
  has_many :category_posts
  has_many :posts, :through => :category_posts
end

class CategoryPost < ActiveRecord::Base
  belongs_to :category
  belongs_to :post
end

class Classroom < ActiveRecord::Base
  has_many :classroom_posts
  has_many :posts, :through => :classroom_posts
end

class ClassroomPost < ActiveRecord::Base
  belongs_to :classroom
  belongs_to :post
end

我想做这样的事情

Post.where(["category.id = ? AND classroom.id = ?", params[:category_id], params[:classroom_id]])

这确实是一个非常简单的任务,但我不知道我应该寻找什么(关键字)。

这和this 是一样的问题,但是在rails 中。

编辑: 我在问题中添加了更多细节。 这有效,但前提是我指定了两个参数。女巫并非总是如此 - 我不知道会指定什么参数。

Post.joins(:categories, :classrooms).where(["categories.id = ? AND classrooms.id = ?", params[:classroom_id], params[:category_id]])

【问题讨论】:

    标签: ruby-on-rails ruby model associations


    【解决方案1】:
    Category.find(params[:category_id]).posts
    

    还可以看看指南:

    【讨论】:

    • 这行得通,谢谢。但是,如果我对该帖子还有一个多对多关联(比如说教室),并且我想按类别和教室查找呢?像 Post.where(["category.id = ? AND classroom.id = ?", params[:category_id], params[:classroom_id]])
    • 这个怎么样:Post.where(["category_id =?", params[:category_id]).where(["classroom_id =?", params[:classroom_id]])
    • @chap 我在 Post 表中没有这些字段。这就是我问的原因。请阅读问题。
    • 您的回答只会帮助找到属于某个类别的帖子,也不会按教室过滤。
    【解决方案2】:

    听起来你需要一个 if 语句。

    if params[:category_id] && params[:classroom_id]
      Post.joins(:categories, :classrooms).where("classrooms.id" => params[:classroom_id], "categories.id" => params[:category_id]])
    elsif params[:category_id]
      Category.find(params[:category_id]).posts
    else
      Classroom.find(params[:classroom_id]).posts
    end
    

    【讨论】:

      【解决方案3】:

      我认为这应该可行:

      Post.joins(:category_posts, :classroom_posts)
      .where(
      ["category_posts.category_id = ? 
      AND classroom_posts.classroom_id = ?", params[:category_id], params[:classroom_id]])
      

      这将转换为类似的 SQL:

      SELECT 
          p.*
      FROM
          posts AS p
              INNER JOIN
          category_posts AS cap ON cap.id = p.category_posts_id
              INNER JOIN
          classroom_posts AS clp ON clpid = p.classroom_posts_id
      WHERE
          cap.category_id = '1' AND clp.classroom_id = '1'
      ;
      

      关于是否使用 :include 或加入 Post 看看这个 answer on stackoverflow。

      【讨论】:

        【解决方案4】:

        这是我在 Rails 3 中要做的事情:

        post.rb:

        def self.in_category(category_id)
          if category_id.present?
            join(:category_posts).where(category_posts: {category_id: category_id})
          else
            self
          end
        end
        
        def self.in_classroom(classroom_id)
          if classroom_id.present?
            join(:classroom_posts).where(classroom_posts: {classroom_id: category_id})
          else
            self
          end
        end
        

        我不加入 ClassroomCategory,因为它为 DBMS 做更多的工作,这不是必需的。

        现在,你可以这样做了:

        Post.in_category(params[:category_id]).in_classroom(params[:classroom_id])
        

        不过我还没有测试过。因此,如果需要,请不要犹豫。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多