Как обновить значение внешнего ключа ide в Laravel Eloquent? - PullRequest
1 голос
/ 12 февраля 2020

Я совершенно новичок в Laravel, и я не смог найти ответ на эту проблему ни в Laravel документах, ни здесь. Я думаю, это просто вопрос того, как его искать, потому что я почти уверен, что это частый случай.

У меня есть две модели отношений (это упрощенный случай), я получаю нужную мне информацию через файл ресурсов, но я не могу понять, как правильно хранить или обновлять информацию. Вот пример кода:

Models\Company.php

class Company extends Model
{
    protected $fillable = [
        'name', 'blablabla', 'country_id', 'blablabla2',
    ];

    public function country() {
        return $this->belongsTo(Country::class);
    }
}
Models\Country.php

class Country extends Model
{
    protected $fillable = [
        'code', 'name', 'prefix', 'tax_code_id',
    ];

    public function companies() {
        return $this->hasMany(Company::class);
    }
}

Тогда у меня есть файл CompanyController для управления запросами API:

Controllers\CompanyController.php

class CompanyController extends BaseController
{
    public function index()
    {
        $companies = Company::paginate();
        $response = CompanyResource::collection($companies)->response()->getData(true);

        return $this->sendResponse($response, 'Companies retrieved successfully');
    }

    public function store(Request $request)
    {
        $input = $request->all();

        $validator = Validator::make($input, $this->validation_rules);

        if($validator->fails()){
            return $this->sendError('Validation error.', $validator->errors());
        }

        $company = Company::create($input);

        return $this->sendResponse($company->toArray(), 'Company added successfully.');
    }
}

...

    public function update(Request $request, Company $company)
    {
        $input = $request->all();

        $validator = Validator::make($input, $this->validation_rules);

        if($validator->fails()){
            return $this->sendError('Validation error.', $validator->errors());
        }

        $company->update($input);

        return $this->sendResponse($company->toArray(), 'Company updated successfully.');
    }

А вот CompanyResource Я использую для отображения информации по мере необходимости.

Resources/CompanyResource.php

class CompanyResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'blablabla' => $this->blablabla,
            'country' => $this->country,
            'blablabla2' => $this->blablabla2,
        ];
    }
}

Поэтому при поиске компаний (или отдельной компании) я получаю вложенное JSON:

{
  "id": "1",
  "name": "something",
  "blablabla": "blablabla",
  "country": {
    "id": "100",
    "code": "MA",
    "name": "Mars",
    "prefix": "123",
    "tax_code_id": "#$%"
  },
  "blablabla2": "blablabla2"
}

Если Я создаю или обновляю новую компанию. Я отправляю полезную нагрузку, которая имеет ту же структуру, что и та, которую я получаю выше, но если я изменяю значение country id, моя модель компании не получает его.

PUT Api/companies/1

{
  "name": "something",
  "blablabla": "blablabla3",
  "country": {
    "id": "200",
    "code": "JU",
    "name": "Jupiter",
    "prefix": "456",
    "tax_code_id": "#=%"
  },
  "blablabla2": "blablabla2"
}

Я ожидаю обновить поле country_id в таблице companies для записи 1, чтобы она соответствовала полезной нагрузке (таким образом, от 100 до 200), но этого не происходит.

Я мог бы отредактировать логи внешнего интерфейса c, чтобы отправлять только полезные данные country_id , поскольку я не собираюсь обновлять таблицу стран и всю эту дополнительную информацию. избыточно, но я хотел бы знать, как управлять им в контроллере с Laravel.

Вы бы мин помогать мне? Заранее спасибо.

1 Ответ

1 голос
/ 12 февраля 2020

Если вы хотите, чтобы он работал с кодом сейчас, вам нужно иметь country_id в root JSON объекте, который вы отправляете. Поскольку это способ, которым вы бы заполнить идентификатор. На мой взгляд, это не лучший подход, но именно поэтому ваше обновление в данный момент не работает.

{
    "name": "something",
    "blablabla": "blablabla3",
    "country_id": 200,
    ...

Мне действительно нравится подход отправки полных объектов. Обычно заполнять идентификаторы не очень хорошо, так как это может помешать работе отношений. Laravel установит ваши отношения, когда вы будете ассоциироваться, в противном случае вам не гарантируется наличие правильных отношений после заполнения.

Поэтому я бы выбрал идентификатор и связал объект страны с компанией. В логи c похоже на это.

// only fill non relation fields, fill used as save is needed after associate()
$company->fill($request->only(['name', 'blabla']));

$company->country()->associate(Country::find($request->get('country')['id']));

//associate does not save
$company->save();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...