ruby-on-rails – 通过虚拟属性选择Rails模型
我有两个导轨型号Section& SectionRevision. Section只是一个容器,它包含与自身相关的所有修订.因此,Section的大部分属性基本上存储在SectionRevision模型中,因此可以随时恢复到Revisions的历史记录.
有时我需要从Sections模型访问最新修订版的属性,所以我创建了一些虚拟属性来解释这个问题. 每个模型都具有这些迁移中定义的属性: 部分: class CreateSections < ActiveRecord::Migration def change create_table :sections do |t| t.integer "page_id",:null => false t.timestamps t.datetime "deleted_at" end add_index("sections","page_id") add_index("sections","current_revision_id") end end SectionRevision: class CreateSectionRevisions < ActiveRecord::Migration def change create_table :section_revisions do |t| t.integer "section_id",:null => false t.integer "parent_section_id" t.integer "position" t.string "title",:default => "",:null => false t.text "body",:null => false t.timestamps end add_index("section_revisions","section_id") add_index("section_revisions","parent_section_id") end end 和模型: SectionRevision: class SectionRevision < ActiveRecord::Base belongs_to :section,:class_name => 'Section',:foreign_key => 'section_id' belongs_to :parent_section,:foreign_key => 'parent_section_id' def parsed_json return JSON.parse(self.body) end end 部分: class Section < ActiveRecord::Base belongs_to :page has_many :revisions,:class_name => 'SectionRevision',:foreign_key => 'section_id' has_many :references def current_revision self.revisions.order('created_at DESC').first end def position self.current_revision.position end def parent_section self.current_revision.parent_section end def children Sections.where(:parent_section => self.id) end end 如你所见,Section有几个虚拟属性,如parent_section,current_revision&位置. 问题是现在我想创建一个虚拟属性,子节点选择虚拟属性parent_section.id等于self.id的所有节.这有可能吗?我知道上面的代码不能用于查询不存在的列 – 而且我不确定如何从模型中访问模型实例’Sections’似乎不起作用. 可以根据虚拟属性执行选择吗? 我已根据ProGNOMmers的答案更新了模型并获得以下内容: class Section < ActiveRecord::Base has_many :revisions,:foreign_key => 'section_id' #Need to somehow modify :child_revisions to only be selected if it is the section_id's current_revision? has_many :child_revisions,:foreign_key => 'parent_section_id' has_many :children,:through => :child_revisions,:source => :section end 情况1:这完全没问题. 1.9.3p392 :040 > section => #<Section id: 3,page_id: 10,created_at: "2013-04-02 01:31:42",updated_at: "2013-04-02 01:31:42",deleted_at: nil> 1.9.3p392 :041 > sub_section => #<Section id: 4,created_at: "2013-04-04 10:19:33",updated_at: "2013-04-04 10:19:33",deleted_at: nil> 1.9.3p392 :042 > revision1 => #<SectionRevision id: 5,section_id: 4,title: "test",body: "[{"type":"testbody"}]",created_at: "2013-04-04 10:21:46",updated_at: "2013-04-04 21:55:10",position: 3,parent_section_id: nil> 1.9.3p392 :043 > revision2 => #<SectionRevision id: 6,created_at: "2013-04-04 12:29:19",updated_at: "2013-04-04 21:55:15",parent_section_id: 3> 1.9.3p392 :044 > sub_section.current_revision SectionRevision Load (0.6ms) SELECT `section_revisions`.* FROM `section_revisions` WHERE `section_revisions`.`section_id` = 4 ORDER BY created_at DESC LIMIT 1 => #<SectionRevision id: 6,parent_section_id: 3> 1.9.3p392 :045 > section.children => [#<Section id: 4,deleted_at: nil>] 情况2: 1.9.3p392 :021 > section => #<Section id: 3,deleted_at: nil> 1.9.3p392 :022 > sub_section => #<Section id: 4,deleted_at: nil> 1.9.3p392 :023 > revision1 => #<SectionRevision id: 5,updated_at: "2013-04-04 10:24:22",parent_section_id: 3> 1.9.3p392 :024 > revision2 => #<SectionRevision id: 6,updated_at: "2013-04-04 12:29:19",parent_section_id: nil> 1.9.3p392 :025 > sub_section.current_revision SectionRevision Load (0.7ms) SELECT `section_revisions`.* FROM `section_revisions` WHERE `section_revisions`.`section_id` = 4 ORDER BY created_at DESC LIMIT 1 => #<SectionRevision id: 6,parent_section_id: nil> 1.9.3p392 :026 > section.children Section Load (0.6ms) SELECT `sections`.* FROM `sections` INNER JOIN `section_revisions` ON `sections`.`id` = `section_revisions`.`section_id` WHERE `section_revisions`.`parent_section_id` = 3 => [#<Section id: 4,deleted_at: nil>] 在情况2中,我希望section.children返回=> [] as sub_section.current_revision.parent_section_id = nil而不是section.id. 换句话说,section.children应该返回.current_revision.parent_section_id = section.id中的所有Sections,但我无法查询.current_revision是一个虚拟属性. 是否有可能将Section.current_revision转换为某种关联?或者也许唯一的方法是在sections表中添加current_revision列? 解决方法
我认为自定义关系非常适合这种情况:
class Section < ActiveRecord::Base has_many :revisions,:foreign_key => 'section_id' has_many :child_revisions,:source => :section end Section.find(42).children #=> SELECT ... WHERE ... AND section_revisions.parent_section = 42 我没有尝试过代码,可能会有错误,但这个想法应该是正确的. 我删除了关于:条件的部分,因为在最后一次编辑后没用 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |