Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Изучаю данный fw, и столкнулся с проблемой У меня есть модель пользователя и в ней есть метод
public function roles()
{
return $this->has_many_and_belongs_to('acl', 'cross_users_acls');
}
Есть две таблицы users и acls в которых соответственно хранятся пользователи и права доступа, таблица cross_users_acls является таблицей пересечений прав доступа и пользователей.
Затем с помощью этого метода я хочу проверить есть ли права на создание пользователя
public function get_new(){
if(Auth::check()&&User::find(Auth::user()->id)->roles()->get()){
return View::make('users.new')
->with('title', 'Добавление нового пользователя');
}else{
return Redirect::to('norights');
}
}
Сам вопрос, что возвращает User::find(Auth::user()->id)->roles()->get()?
Не в сети
PHPUser::find(Auth::user()->id)
А зачем ты сначала получаешь ID пользователя из модели, возвращённой Auth::user(), а затем ищешь эту самую модель в таблице по ID, который из неё же и получил? Почему не просто PHPAuth::user()->roles()->get()
?
- Сам вопрос, что возвращает User::find(Auth::user()->id)->roles()->get()?
Методы отношений возвращают обычный запрос с привязанными условиями, то есть на них можно делать любые методы Query — first(), avg() и т.д. В твоём случае он должен вернуть массив моделей acl (после get()) — кстати, у тебя клсс называется маленькими буквами? В параметре ты передаёшь не имя таблицы, а имя класса модели, обычно это User, ACL и т.п…
И раз это массив код вызовет ошибку, так как тебе надо или first(), или цикл.
Есть перевод хорошей статьи про зависимости.
Не в сети
Спасибо за помощь. Разобрался. А статьи читал, просто не мог понять что он должен именно массив моделей вернуть.
Не в сети
Не в сети
Не в сети
Поскольку уже есть тема по отношениям типа Many-To-Many пожалуй стоит задать вопрос именно в ней.
У меня следующие модели:
— Модель сценария
class Scenario extends Eloquent
{
public static $timestamps = false;
public static $table = 'scenarios';
public function configuration(){
return $this->has_many_and_belongs_to('Configuration','scenario_to_configuration','scenario_id');
}
}
class Configuration extends Eloquent
{
public static $timestamps = false;
public static $table = 'configurations';
public function scenario(){
return $this->has_many_and_belongs_to('Scenario','scenario_to_configuration','configuration_id');
}
}
Один сценарий может входить в множество конфигураций, одна конфигурация может содержать множество сценариев. Для реализации данного типа отношения существует промежуточная таблица:
sqlCREATE TABLE `scenario_to_configuration` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `configuration_id` bigint(20) unsigned NOT NULL, `scenario_id` bigint(20) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
При запросе вида PHP$conf = Scenario::find($id)->configuration()->get();
Получаю сообщение:
SQLSTATE[42S22]: Column not found: 1054 Unknown column ’scenario_to_configuration.created_at’ in ’field list’
SQL: SELECT `configurations`.*, `scenario_to_configuration`.`id` AS `pivot_id`, `scenario_to_configuration`.`created_at` AS `pivot_created_at`, `scenario_to_configuration`.`updated_at` AS `pivot_updated_at`, `scenario_to_configuration`.`scenario_id` AS `pivot_scenario_id`, `scenario_to_configuration`.`configuration_id` AS `pivot_configuration_id` FROM `configurations` INNER JOIN `scenario_to_configuration` ON `configurations`.`id` = `scenario_to_configuration`.`configuration_id` WHERE `scenario_to_configuration`.`scenario_id` = ?
Если в промежуточную таблицу добавить следующие поля:
sql`created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL,
Но хотелось бы разобраться почему так? Ведь в обоих моделях переопределено свойство PHPpublic static $timestamps = false
И таблицы не содержат полей created_at, updated_at. Подскажите как правильно сделать? Нужна ли модель описывающая промежуточную таблицу?
Не в сети
- Но хотелось бы разобраться почему так?
Это беда Eloquent начиная с первой версии. Возможно в Laravel 4 это исправят. В текущей версии всё происходит через класс-модель Laravel\Database\Eloquent\Pivot — по умолчанию она имеет PHP$timestamps = true
. Изменив эту перменную, например, в start.php, ты можешь отменить временны́е поля для всех промежуточных таблиц в своём проекте.
Отменить их для одних, оставив для других, простым образом нельзя, но можно наследовать новый класс отношения has_many_and_belongs_to и в нём перекрыть метод pivot(), который создаёт модель промежуточной таблицы конкретно для этого отношения.
// application/start.php
Laravel\Database\Eloquent\Pivot::$timestamps = false;
См. laravel\database\eloquent\pivot.php и laravel\database\eloquent\relationships\has_many_and_belongs_to.php.
Не в сети
Если в промежуточную таблицу добавить следующие поля:
sql`created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL,Но хотелось бы разобраться почему так? Ведь в обоих моделях переопределено свойство
PHPpublic static $timestamps = false
И таблицы не содержат полей created_at, updated_at. Подскажите как правильно сделать? Нужна ли модель описывающая промежуточную таблицу?
Вот кусок кода из ядра Eloquent:
public function __construct($model, $associated, $table, $foreign, $other)
{
$this->other = $other;
$this->joining = $table ?: $this->joining($model, $associated);
// If the Pivot table is timestamped, we'll set the timestamp columns to be
// fetched when the pivot table models are fetched by the developer else
// the ID will be the only "extra" column fetched in by default.
if (Pivot::$timestamps)
{
$this->with[] = 'created_at';
$this->with[] = 'updated_at';
}
parent::__construct($model, $associated, $foreign);
}
А в модели Pivot по умолчанию стоит
public static $timestamps = true;
Я думаю можно смело поменять на false, даже не заморачиваясь.
Изменено OrlandoST (24.12.2012 13:35:39)
Не в сети
Отменить их для одних, оставив для других, простым образом нельзя, но можно наследовать новый класс отношения has_many_and_belongs_to и в нём перекрыть метод pivot(), который создаёт модель промежуточной таблицы конкретно для этого отношения.
Можно сделать достаточно простым способом. Просто для тех отношений где эти поля нужны, указывать их в явном виде:
return has_many_and_belongs_to->with(array('created_at', 'updated_at'))
А при вставке указывать вторым атрибутом наши поля
$model->many_relation->insert(<массив полей для вставки в модель>, <массив для вставки в Pivot>)
Изменено OrlandoST (24.12.2012 13:47:59)
Не в сети
Не в сети
Ого, похоже у нас появился участник, который не брезгует заглядывать в исходники Laravel. Так держать
Я в Laravel новичек, поэтому приходится заглядывать. Кстати код прекрасно структурирова и документирован.
Программирую на Kohana, уже привычка выработалась к некоторым решениям. А здесь еще не совсем понял логику разработчиков. Хотя то, что вижу, мне пока нравится.
Вот не совсем понял чем было вызвано решение использовать HTTPFoundation.
Не в сети
- Вот не совсем понял чем было вызвано решение использовать HTTPFoundation.
Мне тоже совершенно не понятно, зачем всю эту муть её тянуть — стиль написания совершенно другой, кода в объёме намного больше и его сложнее понять из-за тучи методов getXXX, prepareXXX и т.п. Не спорю, что она может быть более универсальной, в ней меньше ошибок и т.п., но в моих глазах этот аргумент не перевешивает минус за её громоздкость.
Не в сети
Не в сети
Спасибо всем за грамотные советы. Теперь для меня кое-что прояснилось. Надеюсь у меня тоже в скором времени будет получатся разбираться в исходниках ядра Laravel.
Да не за что! Надеюсь помогли хоть советы то??
И вообще надо русское сообщество развивать, так что не стесняйтесь задавать вопросы!
Искать решение чужих проблем это тоже способ изучения фреймворка
Не в сети
Мне тоже совершенно не понятно, зачем
всю эту мутьеё тянуть — стиль написания совершенно другой, кода в объёме намного больше и его сложнее понять из-за тучи методов getXXX, prepareXXX и т.п. Не спорю, что она может быть более универсальной, в ней меньше ошибок и т.п., но в моих глазах этот аргумент не перевешивает минус за её громоздкость.
Возможно откажутся в поздних версиях. По мне код явно чужероден для Laravel. Надо поднять вопрос на англоязычном форуме.
Не в сети
- Да не за что! Надеюсь помогли хоть советы то??
В start.php добавил строку:
PHPLaravel\Database\Eloquent\Pivot::$timestamps = false
теперь все хорошо .
Можно конечно и в 1-M\laravel\database\eloquent\pivot.php переопределить PHPpublic static $timestamps
, тоже работает)
Для моих целей поля `created_at` и `updated_at`не нужны вовсе.
Изменено Dmitriy (03.01.2013 21:45:06)
Не в сети
В start.php добавил строку:
PHPLaravel\Database\Eloquent\Pivot::$timestamps = false
теперь все хорошо.
Можно конечно и в 1-M\laravel\database\eloquent\pivot.php переопределитьPHPpublic static $timestamps
, тоже работает)
Для моих целей поля `created_at` и `updated_at`не нужны вовсе.
Менять код ядра это не совсем ООП подход. Потом забудешь что поменял, и при обновлении версии ядра получишь пляски с бубнами
Первый вариант имхо лучше
Не в сети
Страницы 1