2015-09-10 27 views
5

A User có một (hoặc 0) Company và một số Company thuộc về một và chỉ một User. Tôi cố gắng lưu một công ty cho một người dùng nhưng nó thêm một mục mới trong cơ sở dữ liệu mỗi lần tôi kích hoạt lại phương thức lưu. Đó là một mối quan hệ một, vì vậy tôi mặc dù phương pháp save trên User.Lưu mối quan hệ một đến một trong Laravel

Vì vậy Company có một phương pháp user():

public function user() { 
    return $this->belongsTo(User::class, 'user_id'); 
} 

User có một phương pháp company():

public function company() { 
    return $this->hasOne(Company::class, 'user_id'); 
} 

Tôi đang cố gắng để tiết kiệm (để tạo hoặc cập nhật) Công ty của người dùng như thế này (trong Bộ điều khiển):

$company = new Company(); 
$company->name = 'Test'; 
User::findOrFail(1)->company()->save($company); 

Lần đầu tiên tôi chạy mã này nó tạo ra mục nhập trong cơ sở dữ liệu (OK), nhưng lần thứ hai nó thêm một mục mới cho cùng một người dùng (Không OK). Tôi nghĩ rằng nó sẽ chỉ cập nhật các mục cơ sở dữ liệu.

Đây có phải là trục trặc (hoặc cái gì đó tôi không hiểu trong quan hệ 1-1) trong Laravel hoặc Tôi có làm gì sai không? (tôi suy nghĩ và hy vọng đó là mục đích thứ hai)

+0

Kiểm tra câu trả lời này, nó có thể giúp bạn: http://stackoverflow.com/a/20764237/5122070 –

+0

Cảm ơn, nhưng tôi không chắc chắn nó thực sự giúp cho vấn đề cụ thể này. Vấn đề của tôi là cụ thể hơn. Đó là về tiết kiệm (tạo hoặc cập nhật) trực tiếp trong mối quan hệ –

Trả lời

8

Tạo và cập nhật cần phải điều trị khác nhau. Vì vậy, hãy kiểm tra sự tồn tại của thuộc tính công ty trước tiên.

$user = User::with('company')->findOrFail(1); 
if ($user->company === null) 
{ 
    $company = new Company(['name' => 'Test']); 
    $user->company()->save($company); 
} 
else 
{ 
    $user->company->update(['name' => 'Test']); 
} 

Lưu ý rằng hasOne() không đảm bảo rằng bạn sẽ có mối quan hệ một-một, nó chỉ cho Eloquent cách tạo truy vấn. Nó hoạt động ngay cả khi bạn có nhiều Company tham khảo cùng một User, trong trường hợp này khi bạn gọi $user->company, bạn sẽ nhận được Company đầu tiên trong tập dữ liệu kết quả từ cơ sở dữ liệu.

+0

Ok cảm ơn. "Lưu ý rằng hasOne() không đảm bảo rằng bạn sẽ có mối quan hệ một-một, nó chỉ nói cho Eloquent cách tạo truy vấn" -> Rất hữu ích, Hiện tại đã đủ rõ ràng. –

0

Bạn đang làm sai ở đây

$company = new Company(); 
$company->name = 'Test'; 
User::findOrFail(1)->company()->save($company); 

Bạn đang không nói mà hàng để cập nhật

Vì vậy, mã của bạn phải được sửa đổi như thế này

$companyId là công ty của bạn để cập nhật

$company = new Company(); 
$company->name = 'Test'; 
User::findOrFail(1)->company()->find($companyId)->save($company); 
+0

Nhưng tôi không biết ID công ty vào thời điểm này, tôi chỉ muốn cập nhật giá trị công ty cho một người dùng (mà không phải quan tâm đến người dùng trước đó). Maby nó là không thể, nhưng có vẻ lạ rằng 'save()' không quan tâm đến loại quan hệ (ở đây, nó được mã hóa từ một đến một) –

+0

@ rap-2-h bạn có một hình thức mà bạn đang chuyển thông tin công ty.Nếu người dùng có thông tin về công ty thì sẽ có một id nếu không thì bạn để lại id để trống và khi bạn đăng biểu mẫu bạn nhận được id. Bây giờ nếu có giá trị id bạn tìm thấy và cập nhật hoặc bạn chèn. –

+0

Ok cảm ơn. Tôi biết đó là một giải pháp để sử dụng trường ẩn trong một biểu mẫu, nhưng câu hỏi của tôi là chúng ta nên làm những điều như vậy? Laravel biết rằng nó chỉ có thể là một công ty cho một người dùng, vậy tại sao nó lại thêm một công ty mới khi tôi lưu nó. Nó có vẻ lạ (như thể nó không tôn trọng những gì được tuyên bố), vì vậy tôi nghĩ rằng tôi đang làm sai cách. –

4
$user = User::findOrFail(1); 
$company = $user->company ?: new Company; 
$company->name = 'Test'; 
$user->company()->save($company); 
+0

Cũng giống như cách này! Nhanh chóng và sạch sẽ! +1 :) –

Các vấn đề liên quan