您好我有6个模特彼此关系:
拼写模型,可以有许多标签和元素以及一个戒指(也称为等级)
class Spell < ActiveRecord::Base
belongs_to :spell_ring
has_many :element_of_spells, dependent: :destroy
has_many :spell_elements, through: :element_of_spells
has_many :tag_of_spells, dependent: :destroy
has_many :spell_tags, through: :tag_of_spells
validates_presence_of :name
end
可以有多个法术的法术元素
class SpellElement < ActiveRecord::Base
has_many :element_of_spells, dependent: :destroy
has_many :spells, through: :element_of_spells
end
法术标记,可以有多个法术:
class SpellTag < ActiveRecord::Base
has_many :tag_of_spells, dependent: :destroy
has_many :spells, through: :tag_of_spells
end
法术戒指:
class SpellRing < ActiveRecord::Base
has_many :spells
end
加入模特:
class ElementOfSpell < ActiveRecord::Base
belongs_to :spell
belongs_to :spell_element
end
class TagOfSpell < ActiveRecord::Base
belongs_to :spell
belongs_to :spell_tag
end
好的,现在我想好好利用它们:)
我所知道的:
如果我使用任何spell_tag或spell_element或spell_ring对象,我可以获得所有相关法术。
element = SpellElement.first
spells_of_element = element.spells >> give me all associated spells
我知道我可以用spell_ring_id
来限制它,因为它是拼写对象的一部分。
spell_ring = SpellRing.first
spells_of_element_and_ring = spells_of_element.where( spell_ring_id: spell_ring.id ) >> returns spells of given element and ring
我不知道的事情:
如何使用给定标记范围spells_of_element_and_ring
。
tag = SpellTag.first
spells_of_element_ring_and_tag = ??
更新
我想要什么?
能够查询法术:
以及这三种模式的任意组合。
答案 0 :(得分:1)
在发布到StackOverflow时,最好尽可能多地清除代码,并将问题归结为最简单的示例。这将获得更快的答案,也对更多人有用。
让我们从一个简单的学校例子开始,这个学校有很多教室,每个教室都有很多学生。
让我们创建我们的模型:
rails generate model school name:string
rails generate model classroom school_id:integer grade:integer
rails generate model student name:string classroom_id:integer
现在让我们创建我们的关联:
class School < ActiveRecord::Base
has_many :classrooms
has_many :students, through: :classrooms
end
class Classroom < ActiveRecord::Base
belongs_to :school
has_many :students
end
class Student < ActiveRecord::Base
belongs_to :classroom
end
最后,我们将创建三个快速记录:
school = School.create name: 'City Elementary'
classroom = school.classrooms.create grade: 4
student = classroom.students.create name: 'Bob'
现在我们可以像这样得到学校所有学生的名单:
school.students
这是因为学校has_many
学生,through
教室。
我认为你真正想要的是一点点复杂 - 一个咒语可以有很多元素,一个元素可以属于许多咒语。在这种情况下,您需要一个“连接表”。让我们通过消除除法术和元素之外的所有内容来简化您的示例。
我们首先创建模型:
rails generate model spell name:string
rails generate model element name:string
现在我们创建一个连接表,跟踪哪些法术和元素彼此属于:
rails generate migration create_elements_spells element_id:integer spell_id:integer
现在我们定义我们的关联(关系):
class Element < ActiveRecord::Base
has_and_belongs_to_many :spells
end
class Spell < ActiveRecord::Base
has_and_belongs_to_many :elements
end
has_and_belongs_to_many
按字母顺序自动查找具有两个模型组合名称的表格,复数形式。现在我们可以做以下事情:
spell = Spell.create name: 'set on fire'
flint = Element.create name: 'flint'
steel = Element.create name: 'steel'
spell.elements << flint
spell.elements << steel
现在,spell.elements
列出了燧石和钢铁。 flint.spells
会列出我们的'火上浇油'法术。 steel.spells
也会列出我们的咒语。你可以从那里扩展。
但是如果你需要了解的不仅仅是什么元素 - 如果你需要知道多少呢?现在您有额外的数据不属于拼写记录或元素记录。它属于协会本身。我们可能将元素/数量组合称为“成分”,并为其创建一个表格,如下所示:
rails generate model ingredient spell_id:integer element_id:integer amount:string
我们更新了我们的协会:
class Element < ActiveRecord::Base
has_many :ingredients
has_many :spells, through: :ingredients
end
class Spell < ActiveRecord::Base
has_many :ingredients
has_many :elements, through: :ingredients
end
class Ingredient < ActiveRecord::Base
belongs_to :element
belongs_to :spell
end
现在我们可以为我们的法术添加成分:
spell.ingredients.create element: flint, amount: '1 gram'
spell.ingredients.create element: steel, amount: '1 piece'
因此spell.ingredients
将列出燧石和钢材,以及每种材料的数量。这应该可以帮助您构建应用程序。
答案 1 :(得分:0)
我不知道这是Rails方式。但我发现这样的东西最适合我。
因为SpellElement.spells,SpellRing.spells,SpellTag.spells都返回一个数组。我的想法是只比较它们并仅返回匹配的元素。
所以
spell_element_ring_and_tag = some_spell_element.spells & some_spell_ring.spells & some_spell_tag.spells
将仅返回所有三个阵列共享的拼写对象。