加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 通过虚拟属性选择Rails模型

发布时间:2020-12-17 02:38:21 所属栏目:百科 来源:网络整理
导读:我有两个导轨型号Section SectionRevision. Section只是一个容器,它包含与自身相关的所有修订.因此,Section的大部分属性基本上存储在SectionRevision模型中,因此可以随时恢复到Revisions的历史记录. 有时我需要从Sections模型访问最新修订版的属性,所以我创
我有两个导轨型号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

我没有尝试过代码,可能会有错误,但这个想法应该是正确的.

我删除了关于:条件的部分,因为在最后一次编辑后没用

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读