我正在阅读类表继承(CTI),发现我更喜欢它.我的问题是,单表继承(STI)是否有任何特定用例,您可以在CTI上使用它?
我读了http://rhnh.net/2010/07/02/3-reasons-why-you-should-not-use-single-table-inheritance,据我所知,它很稳固.STI的用例是行为差异而不是数据.
我的代码有问题
class Post < ActiveRecord::Base
end
class NewsArticle < Post
has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at'
end
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true, :counter_cache => true
end
Run Code Online (Sandbox Code Playgroud)
并尝试去获取一些NewsArticle的评论,我在日志中看到类似的东西
Comment Load (0.9ms) SELECT "comments".* FROM "comments" WHERE ("comments"."commentable_id" = 1 and "comments"."commentable_type" = 'Post') ORDER BY created_at
Run Code Online (Sandbox Code Playgroud)
奇怪的是"commentable_type"="发布".怎么了?
PS:Rails 2.3.5 && ruby 1.8.7(2010-01-10 patchlevel 249)[i686-darwin10]
activerecord ruby-on-rails single-table-inheritance polymorphic-associations
我正在使用一个Symfony2/Doctrine应用程序,该应用程序使用类表继承(http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html#class-table-inheritance)管理咨询中的投诉.每个Consult都有很多投诉(OneToMany),每种不同类型的投诉都有不同的结构和外观.投诉是一个集合,并使用JS动态添加.
此时,我能够坚持投诉并通过在持久性之前将它们重新设置为Controller中的相应类型来将它们链接到Consults.我遇到了一些问题,我打算将其迁移到表单事件(http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html)或其他类似的东西来简化流程.
但是,我在这一点上遇到的问题是,我无法使用FormView在视图中显示现有的Complaints,因为表单构建器要求我设置要显示的集合的类型.如果每个Consult只有一种类型的投诉,那就没问题了,但它们可以有多种类型,在表单构建器中设置类型会限制我使用那种类型.
是否有一些方法可以阻止FormView在没有类型的情况下转换为字符串或某种方式在每个投诉的基础上动态检测和分配类型(使用$ complaint-> getComplaintType(),也许)?
<?php
namespace Acme\ConsultBundle\Entity;
class Consult
{
/**
* @ORM\OneToMany(targetEntity="Acme\ConsultBundle\Entity\ComplaintBase", mappedBy="consult", cascade={"persist", "remove"})
*/
protected $complaints;
}
?>
<?php
namespace Acme\ConsultBundle\Entity;
/**
* Acme\ConsultBundle\Entity\ConsultBase
*
* @ORM\Entity
* @ORM\Table(name="ConsultComplaintBase")
* @ORM\HasLifecycleCallbacks
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="complaint_name", type="string")
* @ORM\DiscriminatorMap({
* "ComplaintDefault" = "Acme\ConsultBundle\Entity\ComplaintDefault",
* "ComplaintRosacea" = "Acme\ConsultBundle\Entity\ComplaintRosacea",
* "ComplaintBotox" = "Acme\ConsultBundle\Entity\ComplaintBotox",
* "ComplaintAcne" = "Acme\ConsultBundle\Entity\ComplaintAcne",
* "ComplaintUrticaria" = "Acme\ConsultBundle\Entity\ComplaintUrticaria",
* })
*/
abstract class ComplaintBase
{
/**
* @ORM\ManyToOne(targetEntity="Acme\ConsultBundle\Entity\Consult", inversedBy="complaints")
* @ORM\JoinColumn(name="consult_id", referencedColumnName="id")
*/
protected $consult; …Run Code Online (Sandbox Code Playgroud) forms doctrine single-table-inheritance class-table-inheritance symfony
我已经在这里,这里和这里阅读了帖子,但是我仍然无法实现单表继承.
理想情况下,我希望有两个注册路径(一个用于客户端,一个用于提供者),具有公共字段名称,电子邮件,密码和confirm_password,以及提供者注册具有额外的radiobutton字段以指定提供者类型.我正在通过设计进行注册.在点击注册表单上的提交后,用户将被重定向到第二种形式,这对于客户端和提供者来说是完全不同的(我一直在使用资源的编辑页面).
按照目前的情况,如果我只是通过用户进行操作,一切正常,但只要我添加单表继承,注册表单就会告诉我他们缺少第二种表单的要求.
这是我的 config/routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => {:sessions => "sessions"}, :skip=> :registrations
devise_for :clients, :providers, :skip=> :sessions
resources :clients
resources :providers
root :to=>'pages#home'
match '/home', to: 'pages#home', via: 'get'
end
Run Code Online (Sandbox Code Playgroud)
我的模型如下:
用户:
class User < ActiveRecord::Base
before_save {self.email = email.downcase}
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates :name, presence: true, length: {maximum: 50}
validates :email, presence: true, :email => {:ban_disposable_email => true, :message => I18n.t('validations.errors.models.user.invalid_email')}, uniqueness: { case_sensitive: false …Run Code Online (Sandbox Code Playgroud) ruby-on-rails single-table-inheritance devise ruby-on-rails-4
我有以下类型的hibernate实体层次结构的类.我想要有两个具体的子类Sub1Class和Sub2Class.它们由在field中定义的鉴别器列()分隔MappedSuperClass.有一个抽象的实体类EntitySuperClass,由其他实体引用.其他实体不应该关心它们是否实际引用Sub1Class或Sub2Class.
这实际上可能吗?目前我收到此错误(因为列定义在Sub1Class和EntitySuperClass中继承两次):
Repeated column in mapping for entity: my.package.Sub1Class column: field (should be mapped with insert="false" update="false")
Run Code Online (Sandbox Code Playgroud)
如果我想补充@MappedSuperClass到EntitySuperClass,然后我得到断言错误的的Hiberante:如果一个类既是实体和映射超类它不喜欢.如果我@Entity从中移除EntitySuperClass,则该类不再是实体,并且不能从其他实体引用:
MappedSuperClass 是外部包的一部分,所以如果可能的话,不应该更改.
我的课程:
@MappedSuperclass
public class MappedSuperClass {
private static final String ID_SEQ = "dummy_id_seq";
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ID_SEQ)
@GenericGenerator(name=ID_SEQ, strategy="sequence")
@Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false)
private …Run Code Online (Sandbox Code Playgroud) 我有3个模型使用单表继承.它们适用于可在我们网站上购买的三种不同类型的商品.这些项目被分类,因此Category模型具有用于映射这三种类型中的每一种的属性.
当使用简单的选择来获取所有类别,然后在类别中显示它们的名称和每种类型的项目的数量时,Doctrine总共执行369个查询,总共549毫秒.(一个用于类别列表,然后一个用于类别中的每个类型.)
所以我开始在查询中添加联接以消除所有额外的查询.它适用于第一个项目类型,主查询运行在101.80毫秒.(根据Symfony Profiler工具栏)
$this->_em->createQueryBuilder()
->select([$alias, 'courses'])
->from($this->_entityName, $alias)
->leftJoin("{$alias}.courses", 'courses');
Run Code Online (Sandbox Code Playgroud)
只要我添加第二个连接,查询就会减慢到24050.14毫秒
$qb = $this->_em->createQueryBuilder()
->select([$alias, 'courses', 'bundles'])
->from($this->_entityName, $alias)
->leftJoin("{$alias}.courses", 'courses')
->leftJoin("{$alias}.bundles", 'bundles');
Run Code Online (Sandbox Code Playgroud)
我还没有尝试过第三次加入,担心它会让服务器崩溃.
真正奇怪的是,如果我使用Doctrine查询记录并获得确切的查询,并在我的数据库上手动运行它,它只运行0.2秒.
该表在所有FK列和鉴别器列上都有索引.
任何建议将不胜感激.谢谢!
编辑:4/3
我必须让分支回到其他问题的工作点才能回到这个问题.
SQL小提琴与架构(减去其他未在这种情况下加载的表的FK):http://sqlfiddle.com/#!28/85051
所以,我有没有连接的页面,并且它在820.38毫秒内进行了382次查询以进行延迟加载.当我手动加入,而不是依赖延迟加载,它以130为21159(这是唯一加盟模式2,所以它仍然懒加载第三)
$qb = $this->_em->createQueryBuilder()
->select([$alias, 'courses', 'bundles'])
->from($this->_entityName, $alias)
->leftJoin("{$alias}.courses", 'courses')
->leftJoin("{$alias}.bundles", 'bundles');
Run Code Online (Sandbox Code Playgroud)
这是来自Symfony工具栏的查询(20241.26 ms)
SELECT
i0_.description AS description0,
i0_.id AS id1,
i0_.name AS name2,
i0_.created_at AS created_at3,
i0_.updated_at AS updated_at4,
i0_.display_order AS display_order5,
i1_.atccode AS atccode6,
i1_.version AS version7,
i1_.description AS description8,
i1_.online_price AS online_price9, …Run Code Online (Sandbox Code Playgroud) 我有一个基类通过单表继承继承其他2个.我希望所有子类出于各种原因共享相同的控制器/视图 - 唯一真正的区别在于模型的功能.
但是,当我尝试使用link_to"stuff"时,instance_of_child会收到有关无法找到正确页面的投诉.
我已经尝试搞乱匹配'/ subclass'=> redirect('/ parent'),但这会产生奇怪的链接,没有任何意义.有什么建议?我对rails非常陌生,我承认我对routes.rb的理解仍然有限 - 但是,我并不完全确定这是我应该看的地方.
我有以下继承层次结构:
Task
|
SpecificTask
|
VerySpecificTask
Run Code Online (Sandbox Code Playgroud)
我想坚持使用单表继承,所以我注释了类:
@Entity
@Table(name="task")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Task
@Entity
public class SpecificTask extends Task
@Entity
public class VerySpecificTask extends SpecificTask
Run Code Online (Sandbox Code Playgroud)
当我尝试保存VerySpecificTask类的对象时,我收到一个错误:
Unable to resolve entity name from Class [com.application.task.VerySpecificTask]
expected instance/subclass of [com.application.task.Task]
Run Code Online (Sandbox Code Playgroud)
我错了什么?是否可以将多级继承映射到单个表?
编辑:这是一个蹩脚的错误,我已经很快解决了,所以我删除它以免弄乱这个问题.
java inheritance persistence hibernate single-table-inheritance
我正在使用rails 3.0.9并设计用于身份验证.现在我正在尝试使用单表继承,因为我需要使用多态,所以我有两个类:UserType1和UserType2,它继承自User类.我根据用户的类型正确地需要Devise实例current_user.
例如,
class User < ActiveRecord::Base
#devise and other user logic
end
class UserType1 < User
def get_some_attribute
return "Hello, my type is UserType1"
end
end
class UserType2 < User
def get_some_attribute
return "Hello, my type is UserType2"
end
end
In controller
class MyController < ApplicationController
def action
@message = current_user.get_some_attribute #depending the type using polymorphism
render :my_view
end
end
Run Code Online (Sandbox Code Playgroud) ruby-on-rails single-table-inheritance devise ruby-on-rails-3
(See below for link to sample project)
WHAT I HAVE WORKING:
I have many user types which I am handling using Single Table Inheritance in Rails, e.g.:
class User < ActiveRecord::Base
self.inheritance_column = :meta_type
scope :doctors, -> { where(meta_type: 'Doctor') }
scope :patients, -> { where(meta_type: 'Patient') }
scope :nurses, -> { where(meta_type: 'Nurse') }
scope :employees, -> { where(meta_type: 'Employee') }
end
class Doctor < User
has_many :doctor_patient_relations
has_many :patients, :through => :doctor_patient_relations
has_many :doctor_nurse_relations
has_many :nurses, :through => …Run Code Online (Sandbox Code Playgroud) devise ×2
hibernate ×2
java ×2
symfony ×2
activerecord ×1
controller ×1
doctrine ×1
doctrine-orm ×1
forms ×1
inheritance ×1
mysql ×1
persistence ×1
php ×1
ruby ×1