Laravel объединяет два массива, используя точечную запись - PullRequest
0 голосов
/ 26 февраля 2019

Я думаю, что мой мозг сегодня не функционирует, так как я не могу разобраться с этим.

У меня есть класс с массивом данных, например -

class Testing {

    protected $fillable = ['questions.*.checked'];

    protected $data = [
        'active' => true,
        'questions' => [
            [
                'question' => 'This is the first question',
                'checked' => true,
            ],
            [
                'question' => 'This is the second question',
                'checked' => false,
            ]
         ]
    ];

    public function fill(array $attributes = []) {
        // take our attributes array, check if the key exists in
        // fillable, and if it does then populate our $data property
    }

}

Я хотел бы сделать следующее: если я передам следующий массив методу Testing::fill(), он обновит только соответствующие атрибуты, которые считаются заполняемыми.

Например, передав следующий массив

[
    'active' => false,
    'questions' => [
        [
            'question' => 'This is the first question',
            'checked' => true,
        ],
        [
            'question' => 'This is the second question',
            'checked' => true,
        ]
    ]
]

Изменяет только отмеченные флажки на объекте, а все остальное будет игнорироваться - только помечая свойства $ data attribute questions.*.checked как true

Я чувствую, что естьрешение с помощью помощников Ларавела, но я просто не могу прийти к нему, или, может быть, я поступаю неправильно ...

В конечном счете, я просто хочу некоторый уровень очистки, чтобы, когда вся структураотправляется обратно в метод заполнения объектов, только некоторые элементы могут быть обновлены (как метод заполнения Laravel, только глубже с динамическими значениями).Проблема в том, что то, что на самом деле содержится в $ data, является динамическим, поэтому может быть один вопрос, может быть 100 ...

1 Ответ

0 голосов
/ 26 февраля 2019

Хорошо, я придумала решение, которое делает эту работу, но я надеялась, что там было что-то, немного более ориентированное на Laravel.


protected function isFillable($key)
{
    // loop through our objects fillables
    foreach ($this->fillable as $fillable) {

        // determine if we have a match
        if ($fillable === $key
            || preg_match('/' . str_replace('*', '([0-9A-Z]+)', $fillable) . '/i', $key)
        ) {
            return true;
        }
    }

    // return false by default
    return false;
}

public function fill(array $attributes = [])
{
    // convert our attributes to dot notation
    $attributes = Arr::dot($attributes);

    // loop through each attribute
    foreach ($attributes as $key => $value) {

        // check our attribute is fillable and already exists...
        if ($this->isFillable($key)
            && !(Arr::get($this->data, $key, 'void') === 'void')
        ) {

            // set our attribute against our data
            Arr::set($this->data, $key, $value);
        }
    }

    // return ourself
    return $this;
}

Итак, в приведенном выше, когда я звонюМетод fill (), я конвертирую все атрибуты в точечную нотацию Laravel, используя Arr::dot().Это облегчает цикл для массива и позволяет мне выполнять те проверки, которые я ищу.

Затем я создал метод isFillable(), чтобы определить, существует ли ключ атрибутов в наших объектах $fillable собственность.Если используется подстановочный знак, он преобразует звезды (*) в регулярные выражения, а затем проверяет, есть ли совпадение.Перед выполнением регулярного выражения он выполняет базовую проверку сравнения, в идеале надеясь обойти регулярное выражение и улучшить общую производительность там, где это возможно.

Итак, наконец, если наш атрибут является заполняемым, и мы можем получить значение изнаш массив данных уже, тогда мы позволим этому значению обновиться, используя Arr::set()

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