A Person可以有很多Events,每个都Event可以有一个多态Eventable记录.如何指定记录Person与Eventable记录之间的关系?
以下是我的模型:
class Event < ActiveRecord::Base
belongs_to :person
belongs_to :eventable, :polymorphic => true
end
class Meal < ActiveRecord::Base
has_one :event, :as => eventable
end
class Workout < ActiveRecord::Base
has_one :event, :as => eventable
end
Run Code Online (Sandbox Code Playgroud)
主要问题涉及到Person班级:
class Person < ActiveRecord::Base
has_many :events
has_many :eventables, :through => :events # is this correct???
end
Run Code Online (Sandbox Code Playgroud)
我是否has_many :eventables, :through => :events像上面那样说?
或者我必须像这样拼写它们:
has_many :meals, :through => :events
has_many :workouts, …Run Code Online (Sandbox Code Playgroud) activerecord ruby-on-rails has-many-through polymorphic-associations
查看评论以获取更新.
我一直在努力在这个问题上得到明确而直截了当的答案,我希望这次我能得到它!:D我肯定还有很多东西需要学习Rails,但我确实理解我面临的问题,并且非常感谢额外的帮助.
因此,我认为任务与子目标的子类之间的多对多关系是有序的.更详细地说,我将能够在控制台(当然还有其他地方)做这样的事情:
task = Task.find(1)
task.targets
[...array of all the subclasses of Target here...]
Run Code Online (Sandbox Code Playgroud)
但!假设存在"存储","软件","办公室","车辆"等模型,它们都是"目标"的子类,那么在另一个方向上遍历关系也会很好:
store = Store.find(1)
store.tasks
[...array of all the Tasks this Store is related to...]
software = Software.find(18)
software.tasks
[...array of all the Tasks this Software is related to...]
Run Code Online (Sandbox Code Playgroud)
多态关系隐含的数据库表似乎能够进行这种遍历,但我在尝试寻找一个能够打败多态关系精神的答案时看到一些反复出现的主题:
它似乎是导轨功能或集体社区知识中的一个小漏洞.所以希望stackoverflow可以记录我的搜索答案!
感谢所有帮助的人!
我读了这篇有趣的文章,关于使用多态来在Rails中创建更好的活动源.
我们最终得到类似的东西
class Activity < ActiveRecord::Base
belongs_to :subject, polymorphic: true
end
Run Code Online (Sandbox Code Playgroud)
现在,如果其中两个主题是例如:
class Event < ActiveRecord::Base
has_many :guests
after_create :create_activities
has_one :activity, as: :subject, dependent: :destroy
end
class Image < ActiveRecord::Base
has_many :tags
after_create :create_activities
has_one :activity, as: :subject, dependent: :destroy
end
Run Code Online (Sandbox Code Playgroud)
将create_activities定义为
def create_activities
Activity.create(subject: self)
end
Run Code Online (Sandbox Code Playgroud)
客人和标签定义为:
class Guest < ActiveRecord::Base
belongs_to :event
end
class Tag < ActiveRecord::Base
belongs_to :image
end
Run Code Online (Sandbox Code Playgroud)
如果我们查询记录的最后20个活动,我们可以这样做:
Activity.order(created_at: :desc).limit(20)
Run Code Online (Sandbox Code Playgroud)
我们有第一个N + 1查询问题,我们可以通过以下方式解决:
Activity.includes(:subject).order(created_at: :desc).limit(20)
Run Code Online (Sandbox Code Playgroud)
但是,当我们呼叫访客或标签时,我们会遇到另一个N + 1查询问题.
为了能够使用分页,解决这个问题的正确方法是什么?
performance activerecord ruby-on-rails polymorphic-associations
我可以在没有任何n + 1问题的情况下急切加载多态关系/模型.但是,如果我尝试访问与多态模型相关的模型,则会出现n + 1问题,而我似乎无法找到修复.以下是在本地查看的确切设置:
1)DB表名/数据
history

companies

products

services

2)模型
// History
class History extends Eloquent {
protected $table = 'history';
public function historable(){
return $this->morphTo();
}
}
// Company
class Company extends Eloquent {
protected $table = 'companies';
// each company has many products
public function products() {
return $this->hasMany('Product');
}
// each company has many services
public function services() {
return $this->hasMany('Service');
}
}
// Product
class Product extends Eloquent {
// each product belongs to a …Run Code Online (Sandbox Code Playgroud) polymorphism polymorphic-associations eager-loading laravel eloquent
我尝试创建一个多态关联,这在Rails中很常见,但遗憾的是在Yii2中没有.作为实现的一部分,我需要定义关系:
public function getImages()
{
return $this->hasMany(RecipeImage::className(),
['imageable_id' => 'id', 'imageable_type' => 'Person']);
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为'Person'被视为当前模型的属性,但它是一个常量(多态关联的类名).
如果我尝试使用'andWhere',它当然会在WHERE子句而不是ON子句中添加条件,导致只返回包含现有图像的记录.
public function getImages()
{
return $this->hasMany(RecipeImage::className(), ['imageable_id' => 'id'])->
andWhere(['imageable_type' => 'Ingredient']);
}
Run Code Online (Sandbox Code Playgroud)
我该如何定义关系?没有andOn方法.
假设您正在设置数据库来存储各种车辆的碰撞测试数据.您想存储快艇,汽车和卡丁车的碰撞测试数据.
您可以创建三个单独的表:SpeedboatTests,CarTests和GokartTests.但是每个表中的很多列都是相同的(例如,执行测试的人员的员工ID,碰撞的方向(正面,侧面,后面)等).但是,很多列都会有所不同,因此您不希望将所有测试数据放在一个表中,因为您将拥有相当多的列,对于快艇来说总是为空,相当多的列始终是对于汽车来说是零,而对于卡丁车来说,相当多的都是空的.
假设您还想存储一些与测试没有直接关系的信息(例如正在测试的东西的设计者的员工ID).这些列根本不适合放入"测试"表,特别是因为它们将在同一车辆上的所有测试中重复使用.
让我说明一种可能的表格排列,以便您可以看到所涉及的问题.
Speedboats id | col_about_speedboats_but_not_tests1 | col_about_speedboats_but_not_tests2 Cars id | col_about_cars_but_not_tests1 | col_about_cars_but_not_tests2 Gokarts id | col_about_gokarts_but_not_tests1 | col_about_gokarts_but_not_tests2 Tests id | type | id_in_type | col_about_all_tests1 | col_about_all_tests2 (id_in_type will refer to the id column of one of the next three tables, depending on the value of type) SpeedboatTests id | speedboat_id | col_about_speedboat_tests1 | col_about_speedboat_tests2 CarTests id | car_id | col_about_car_tests1 | col_about_car_tests2 GokartTests id | gokart_id | col_about_gokart_tests1 | col_about_gokart_tests2
这个结构的优点/缺点是什么,实现这样的优先方式是什么?
如果还有一些信息适用于您希望在车辆表中使用的所有车辆,该怎么办?那么CarTests表看起来像......
id | …
database-design polymorphic-associations class-table-inheritance
我正在尝试建立一个多态一对一的关系(has_one和belongs_to的多态等价物).我有一个Address模型,还有其他几个我希望有一个地址的模型.但是,我对文档的措辞感到困惑.我已经看过这个morphMany方法,但我的问题是:我应该使用morphMany即使我只想要它有一个地址,还是有类似morphOne我应该使用的方法?
编辑:我的Address模型有这些字段,只是为了帮助可视化:
Schema::create('addresses', function ($table)
{
$table->increments('id');
$table->string('street');
$table->string('street_more')->nullable();
$table->string('city');
$table->string('state')->nullable();
$table->string('country');
$table->string('postal_code');
$table->integer('addressable_id');
$table->string('addressable_type');
});
Run Code Online (Sandbox Code Playgroud) 我对Rails比较陌生.我想为使用多态关联的模型添加关联,但只返回特定类型的模型,例如:
class Note < ActiveRecord::Base
# The true polymorphic association
belongs_to :subject, polymorphic: true
# Same as subject but where subject_type is 'Volunteer'
belongs_to :volunteer, source_association: :subject
# Same as subject but where subject_type is 'Participation'
belongs_to :participation, source_association: :subject
end
Run Code Online (Sandbox Code Playgroud)
我通过阅读有关ApiDock的关联尝试了大量的组合,但似乎没有任何东西完全符合我的要求.这是我迄今为止最好的:
class Note < ActiveRecord::Base
belongs_to :subject, polymorphic: true
belongs_to :volunteer, class_name: "Volunteer", foreign_key: :subject_id, conditions: {notes: {subject_type: "Volunteer"}}
belongs_to :participation, class_name: "Participation", foreign_key: :subject_id, conditions: {notes: {subject_type: "Participation"}}
end
Run Code Online (Sandbox Code Playgroud)
我希望它通过这个测试:
describe Note do
context 'on volunteer' do
let!(:volunteer) …Run Code Online (Sandbox Code Playgroud) 我有一个Org模型和一个Tag模型.我想将标签与组织关联起来.我的数据库表和Eloquent模型都是这样设置的......
org
id - integer
name - string
...
tags
id - integer
name - string
taggables
id - integer
taggable_id - integer
taggable_type - string
// app/models/Org.php
class Org extends Eloquent
{
protected $table = "org";
...
public function tags()
{
return $this->morphToMany('Tag', 'taggable');
}
}
// app/models/Tag.php
class Tag extends Eloquent
{
protected $table = "tags";
public $timestamps = false;
public function org()
{
return $this->morphedByMany('Org', 'taggable');
}
}
Run Code Online (Sandbox Code Playgroud)
在我看来,我有一个带有多个选择框的表单,用户可以在其中选择他/她想要与组织关联的标签...
...
{{ Form::select('tags[]', $tag_options, null, array(
'multiple',
'data-placeholder' …Run Code Online (Sandbox Code Playgroud) 设置外键约束的常用方法是选择外键指向哪个表.
我在1个表和一组表之间有多态关系.
这意味着该表将与集合中的其中一个表有关系.
例如.
images: person_id, person_type
subordinates: id, col1, col2...col9
products: id, colA, colB...colZ
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,如果person_type是"subordinates",那么person_id应该是subordinates.id的外键,并且产品也是如此.
所以我想知道,是否有可能将一个外键用于其中一个表,或者你必须专门设置它在指定一个表时指向哪个表.
这个问题适用于MySQL和PostgreSQL.
谢谢
eloquent ×3
activerecord ×2
laravel ×2
laravel-4 ×2
database ×1
has-many ×1
mysql ×1
performance ×1
polymorphism ×1
postgresql ×1
relation ×1
yii2 ×1