我试图通过急切加载避免N + 1查询问题,但它无法正常工作.相关模型仍在单独加载.
以下是相关的ActiveRecords及其关系:
class Player < ActiveRecord::Base
has_one :tableau
end
Class Tableau < ActiveRecord::Base
belongs_to :player
has_many :tableau_cards
has_many :deck_cards, :through => :tableau_cards
end
Class TableauCard < ActiveRecord::Base
belongs_to :tableau
belongs_to :deck_card, :include => :card
end
class DeckCard < ActiveRecord::Base
belongs_to :card
has_many :tableaus, :through => :tableau_cards
end
class Card < ActiveRecord::Base
has_many :deck_cards
end
class Turn < ActiveRecord::Base
belongs_to :game
end
Run Code Online (Sandbox Code Playgroud)
我正在使用的查询是在Player的这个方法中:
def tableau_contains(card_id)
self.tableau.tableau_cards = TableauCard.find :all, :include => [ {:deck_card => (:card)}], :conditions => ['tableau_cards.tableau_id = …Run Code Online (Sandbox Code Playgroud) 有没有办法进行第二次查询并复制预先加载的功能?让我们说一个真实的基本例子.一个人有很多车,一辆车有很多零件..
通常情况下,你会说:
person.cars.includes(:parts)
Run Code Online (Sandbox Code Playgroud)
我真的不明白这是做什么的......它只是在内存中加载其他对象吗?它们是否在这一点上与每辆车相关联,然后只是共享密钥?如果只是共享密钥..我可以在内存中加载这些"部件"并在不明确调用"包含"的情况下访问它们吗?例如..类似于:
cars = person.cars
cars_id_array << insert cars ids here
parts = Parts.where(:user_id => person_id, "car_id IN cars_id_array") (just an example)
Run Code Online (Sandbox Code Playgroud)
在这种情况下(假设我做了写代码,我确定我没有..我可以去car1.parts,car2.parts,那些部分是否已经加载到内存中?
如果不是,那么渴望加载的是什么?
我正在尝试优化我们的一些查询.一个特别的挑战是试图加载多态模型.在这种情况下,UserView是多态的,并具有以下列:
user_id, user_viewable_id, user_viewable_type
Run Code Online (Sandbox Code Playgroud)
当我尝试运行此查询时.
@user_views = UserView.select('user_views.* AS user_views, songs.* AS songs, users.* AS users')
.joins('INNER JOIN users AS users ON user_views.user_id = users.id')
.joins('INNER JOIN songs AS songs ON user_views.user_viewable_id = songs.id')
.where(:user_viewable_type => 'Song').order('user_views.id DESC').limit(5)
Run Code Online (Sandbox Code Playgroud)
它似乎并不急于加载查询.我正在使用名为MiniProfiler的gem ,它表示它实际上运行的是n + 1个查询,而不是一个.
以下AR查询返回此SQL:
SELECT user_views.* AS user_views, songs.* AS songs, users.* AS users FROM "user_views" INNER JOIN users AS users ON user_views.user_id = users.id INNER JOIN songs AS songs ON user_views.user_viewable_id = songs.id WHERE "user_views"."user_viewable_type" = …Run Code Online (Sandbox Code Playgroud) polymorphism activerecord ruby-on-rails eager-loading ruby-on-rails-3
我是laravel的新手,并创建一个基本的应用程序来控制关系.我实现了一对一的关系,并希望从基表和相关表中获取特定的列.我有两个表,即users和identity_cards.Relationship定义如下
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
//protected $hidden = array('password', 'remember_token');
protected $fillable = array('first_name','last_name','email','created_at','updated_at');
public function identity_cards()
{
return $this->hasOne('IdentityCard');
}
}
class IdentityCard extends Eloquent {
protected $table = 'identity_cards';
protected $fillable = array('issuance_date','expiry_date','issuance_location','user_id');
public $timestamps = false;
public …Run Code Online (Sandbox Code Playgroud) 任何人都可以帮助我理解为什么以下代码工作
$x = $widget->objGallery->galleryItems()->with(array('captions' => function($query){ $query->where('locale', 'IT' );}))->get() ;
Run Code Online (Sandbox Code Playgroud)
但是当我使用动态值时
$id='11';
$x = $widget->objGallery->galleryItems()->with(array('captions' => function($query){ $query->where('locale', $id );}))->get() ;
Run Code Online (Sandbox Code Playgroud)
在说
方法Illuminate\View\View :: __ toString()不得抛出异常
在我的一个控制器中,我有以下内容:
return Lot::with(array('region', 'territory', 'manager')) -> get();
Run Code Online (Sandbox Code Playgroud)
这很完美,并返回以下内容:
Array
(
[0] => stdClass Object
(
[id] => 1
[region_id] => 3
[territory_id] => 2
[state_id] => 5
[manager_id] => 2
[lot_num] => 0
[lot_type] => managed
[name] => Some Name
[address_1] => Some Address
[address_2] =>
[address_3] =>
[city] => Some City
[zip] => 00000
[opened_at] =>
[deleted_at] =>
[created_at] => 2014-11-06 00:49:39
[updated_at] => 2014-11-06 00:49:39
[region] => stdClass Object
(
[id] => 3
[name] => Corporate
[deleted_at] => …Run Code Online (Sandbox Code Playgroud) 我有代码可以工作,但没有急切加载嵌套关系.
$projects = Project::with('organization')
->leftJoin('stages', 'stages.project_id', '=', 'projects.id')
->leftJoin('activities', 'activities.stage_id', '=', 'stages.id')
->leftJoin('tasks', 'tasks.activity_id', '=', 'activities.id')
->select('projects.*', DB::raw('SUM(IF(tasks.status = 4, score, 0)) AS score'),
DB::raw('SUM(tasks.score) AS total_score'))
->groupBy('projects.id')
->get();
Run Code Online (Sandbox Code Playgroud)
我想通过急切加载嵌套关系来做到这一点,如果我没有这些自定义选择(total_score和得分),我会做
$projects = Project::with('stages.activities.tasks');
Run Code Online (Sandbox Code Playgroud)
但问题出现在那些自定义选择(得分和total_score)上.我尝试了类似的东西,但没有奏效
$projects = Project::with(['stages', 'activities', 'tasks' => function($q) {
$q->select( DB::raw('SUM(IF(tasks.status = 4, score, 0)) AS score'),
DB::raw('SUM(tasks.score) AS total_score'));
}])->get();
Run Code Online (Sandbox Code Playgroud) 我正在使用Rails 4.1和我的模型:
Client has_many TicketLists
TicketList has many projects
Run Code Online (Sandbox Code Playgroud)
现在,我正在尝试在客户端模型中使用eager loading,例如:
class Client < ActiveRecord::Base
def ticket_lists_with_project_id(project_id)
ticket_lists.includes(:projects).where("projects.id = ?", project_id)
end
end
Run Code Online (Sandbox Code Playgroud)
当我这样做时:
Client.find(2).ticket_lists_with_project_id(1)
Client Load (1.7ms) SELECT "clients".* FROM "clients" WHERE "clients"."is_destroyed" = 'f' AND "clients"."is_closed" = 'f' AND "clients"."id" = $1 LIMIT 1 [["id", 2]]
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "projects"
LINE 1: ...d" = 'f' AND "ticket_lists"."client_id" = $1 AND (projects.i...
^
: SELECT "ticket_lists".* FROM "ticket_lists" WHERE "ticket_lists"."is_destroyed" = 'f' AND "ticket_lists"."client_id" = …Run Code Online (Sandbox Code Playgroud) 我有四个模型Tehsil,Ilr,Patwar和Villages。他们的联系是
Tehsil-> 1:m-> Ilr-> 1:m-> Patwar-> 1:m->村庄
我想对所有四个模型应用订单。
查询:
var tehsilQuery = {
include: [{
model: Ilr,
as: 'GirdawariKanoongo',
include: [{
model: Patwar,
as: 'GirdawariPatwar',
include: [{
model: Villages,
as: 'GirdawariVillages',
}]
}]
}],
order: [
['tehsil_name', 'ASC'],
[ {model: Ilr, as: 'GirdawariKanoongo'}, 'kanoongo_name', 'ASC'],
[ {model: Patwar, as: 'GirdawariPatwar'}, 'patwar_area', 'ASC'],
[ {model: Villages, as: 'GirdawariVillages'}, 'village_name', 'ASC'],
]
};
return Tehsils.findAll(tehsilQuery);
[Error: 'girdawari_patwar' in order / group clause is not valid association]
Run Code Online (Sandbox Code Playgroud)
如果我从中删除Patwar和Villages(经纬度两个模型),则order by工作正常 …
我知道我可以渴望或懒惰地在Laravel中建立关系。我也知道关系对象基本上是伪装的查询对象,并且调用会$user->load('teams')执行该查询并将其添加到$ user对象中(即使我不知道该怎么精确)。
假设我有一位User从评论中获得积分的人。为了在数据库调用中获取用户的分数,我将执行以下操作:
SELECT `user_id`, sum(`points`) AS `total_points` FROM `user_comments` where `id` = ?
Run Code Online (Sandbox Code Playgroud)
如果我想一次全部加载它们,我将运行以下查询:
SELECT `users`.*, sum(`user_comments`.`points`) AS `total_points`
FROM `users` LEFT JOIN `user_points` ON `users`.`id` = `user_comments`.`user_id`
GROUP BY `users`.`id`
Run Code Online (Sandbox Code Playgroud)
我想使用Laravel完成这些任务。我喜欢写这样的事情
User::where('age', '>', 40)->with('total_points')->get();
Run Code Online (Sandbox Code Playgroud)
并像这样访问值
$user->total_points
Run Code Online (Sandbox Code Playgroud)
同时加载用户及其总分。我希望可能会有很多很多记录,并且不想每次有用户时都总是调用数据库联接查询。如果我只需要它们的总分值,我也不想不为每个用户自己加载所有注释。
有没有一种方法可以使用关系生成器在Laravel中完成此任务?
eager-loading ×10
activerecord ×4
laravel ×4
eloquent ×2
php ×2
associations ×1
closures ×1
laravel-4 ×1
laravel-5 ×1
model ×1
node.js ×1
polymorphism ×1
relationship ×1
sequelize.js ×1