Как получить виртуальные атрибуты в CakePHP (используя код, а не SQL), как это реализовано в Ruby on Rails - PullRequest
0 голосов
/ 29 декабря 2010

Источник: http://asciicasts.com/episodes/16-virtual-attributes

Я хотел бы выполнить настройку, аналогичную приведенной ниже, но в CakePHP и где виртуальные атрибуты создаются с использованием кода, а не SQL (как описано в http://book.cakephp.org/view/1070/Additional-Methods-and-Properties#Using-virtualFields-1590).

class User < ActiveRecord::Base  
  # Getter  
  def full_name  
    [first_name, last_name].join(' ')  
  end  

  # Setter  
  def full_name=(name)  
    split = name.split(' ', 2)  
    self.first_name = split.first  
    self.last_name = split.last  
  end  
end

Ответы [ 2 ]

2 голосов
/ 29 декабря 2010

Как вы правильно заметили, virtualFields используются для создания дополнительных атрибутов для моделей, использующих SQL.Для генерации полей с использованием кода вы должны попробовать метод afterFind:

function afterFind($results) {
    foreach ($results as $key => $val) {
        if (isset($val['User']['first_name']) && isset($val['User']['last_name'])) {
            $results[$key]['User']['full_name'] = $this->formatName($val['User']['first_name'], $val['User']['last_name']);
        }
    }
    return $results;
}

function formatName($firstName, $lastName) {
    $firstName = trim($firstName);
    $lastName = trim($lastName);
    return $lastName . ', ' . $firstName;
}

Подробнее об этом вы можете прочитать в книге здесь .Я предполагаю, что вам придется проверить это немного дальше, и, возможно, включить второй параметр afterFind метода $primary.


РЕДАКТИРОВАТЬ: Я только что понялдругой способ сделать это - включить такие функции непосредственно в вашу модель:

function getFullName($user = null) {
    if ($user) {
        $this->set($user);
    }
    return $this->data['User']['first_name'] . ' ' . $this->data['User']['last_name'];
}

И вот ваш получатель!

1 голос
/ 29 декабря 2010

Вы можете использовать обратный вызов beforeSave и afterFind.Вот мой код:

class User extends AppModel {

    // Setter
    function beforeSave() {
        if(!empty($this->data['User']['full_name'])) {
            list($this->data['User']['first_name'], $this->data['User']['last_name']) = explode(" ", $this->data['User']['full_name']);
        }

        return true
    }

    // Getter
    function afterFind(array $results, bool $primary) {
        foreach($results as $key => $result) {
            $result['User']['full_name'] = $result['User']['first_name'] + " " + $result['User']['last_name'];

            $results[$key] = $result;
        }

        return $results;
    }
} 

Но я думаю, что SQL-конкат будет быстрее, чем PHP-конкатат.Поэтому я думаю (если вы можете) использовать виртуальные поля будет лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...