Ruby on rails 模型有多个,有多个:通过一个?
我有一套类别,属于一套类别。 这些类别本身可以有多种类别(自指)和问题。 模型及其关系的定义和可视化如下:Ruby on rails 模型有多个,有多个:通过一个?,ruby-on-rails,activerecord,relationship,rails-models,Ruby On Rails,Activerecord,Relationship,Rails Models,我有一套类别,属于一套类别。 这些类别本身可以有多种类别(自指)和问题。 模型及其关系的定义和可视化如下: class CategorySet < ActiveRecord::Base has_many :categories end class Category < ActiveRecord::Base belongs_to :category_set belongs_to :parent_category, :class_name => "Category"
class CategorySet < ActiveRecord::Base
has_many :categories
end
class Category < ActiveRecord::Base
belongs_to :category_set
belongs_to :parent_category, :class_name => "Category"
has_many :categories, :class_name => "Category", :foreign_key => "parent_category_id", dependent: :destroy
has_many :questions, dependent: :destroy
end
class Question < ActiveRecord::Base
belongs_to :category
end
Abbrev to CS, C and Q:
CS
|- C
|- Q
|
|- C
|
|- C
| |- Q
|
|- C
|- Q
|- Q
class CategorySet“类别”
有多个:categories,:class\u name=>“Category”,:foreign\u key=>“parent\u Category\u id”,dependent::destroy
有很多:问题,依赖::破坏
结束
类问题
我希望能够询问CategorySet.find(1).问题,并返回树中的所有问题,无论位置如何。我能想到的唯一方法是使用大量基于函数的请求,并且可能会过度使用sql语句(参见下面的示例)
调用CategorySet.find(1).categories仅查找类别集的直系子类别。另外,Category.find(id).questions只返回该类别的问题
我已经尝试过覆盖类别上的.questions方法,但这似乎不是很好,必须有更好的方法吗?Alo这意味着我不能进行分类设置。包括(:问题)。所有样式语法都大大减少了数据库服务器上的负载方法1 用于此
很抱歉,我给了你一张应得的选票,但忘了把它标为被接受。我基于以上实现了一个解决方案,效果非常好。谢谢
class CategorySet < ActiveRecord::Base
has_many :categories
def questions
categories.map do |c|
c.self_and_descendants.include(:questions).map(&:questions)
end.flatten
end
end
class Category < ActiveRecord::Base
awesome_nested_set
belongs_to :category_set
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
awesome_nested_set
has_many :questions
# add a boolean column called category_set
def questions
join_sql = self_and_descendants.select(:id).to_sql
Question.joins("JOIN (#{join_sql}) x ON x.id = questions.id")
end
end
class Question < ActiveRecord::Base
belongs_to :category
validates :category_id, :presence => true, :category_set => true
end
# lib/category_set_validator.rb
class CategorySetValidator < ActiveModel::EachValidator
def validate_each(object, attribute, value)
if record.category.present? and record.category.category_set?
record.errors[attribute] << (options[:message] ||
"is pointing to a category set")
end
end
end
cs.questions.limit(10).offset(0)
cs.questions.paginate(:page => params[:page]) # if you are using will_paginate