teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

scopeOfのOfは不要だったため削除

2017/11/22 01:33

投稿

masaya_ohashi
masaya_ohashi

スコア9210

answer CHANGED
@@ -17,7 +17,7 @@
17
17
  return $this->$column; // カラム名を変数を使って指定
18
18
  }
19
19
 
20
- public function scopeOfOrderByMyPrice($query) {
20
+ public function scopeOrderByMyPrice($query) {
21
21
  return $query->orderBy($this->myPriceColumnName(), 'asc'); // scope処理でorderByを付ける
22
22
  }
23
23
  }
@@ -51,7 +51,7 @@
51
51
  return $this->hasMany(Price::class);
52
52
  }
53
53
 
54
- public function scopeOfOrderByMyPrice($query) {
54
+ public function scopeOrderByMyPrice($query) {
55
55
  if (\Auth::User()->role == 'admin') {
56
56
  $query
57
57
  ->select(

2

Ofが抜けていたので修正

2017/11/22 01:33

投稿

masaya_ohashi
masaya_ohashi

スコア9210

answer CHANGED
@@ -51,7 +51,7 @@
51
51
  return $this->hasMany(Price::class);
52
52
  }
53
53
 
54
- public function scopeOrderByMyPrice($query) {
54
+ public function scopeOfOrderByMyPrice($query) {
55
55
  if (\Auth::User()->role == 'admin') {
56
56
  $query
57
57
  ->select(

1

仕様変更後

2017/11/20 09:47

投稿

masaya_ohashi
masaya_ohashi

スコア9210

answer CHANGED
@@ -27,4 +27,49 @@
27
27
  $itemList = Item::where('aaa', 'bbb')
28
28
  ->orderByMyPrice() // scopeXXXという名前のメソッドはクエリビルダでこうやって呼べる
29
29
  ->paginate(20);
30
- ```
30
+ ```
31
+
32
+ ### 仕様変更後
33
+ 正直仕様が複雑すぎて、PHP側の処理とSQL側の処理を共通化して書くとか無理です…同じ動作をするように力技でSQLを書くしかないかと思います。
34
+
35
+ 全然動作確認してないので、このまま正しく動くかどうかはわかりませんが…joinとかDB::rawのサブクエリを使えばどうにかできるかと思います。
36
+ ```PHP
37
+ class Item extends Model
38
+ {
39
+ public function myPrice () {
40
+ if (\Auth::User()->role == 'admin') {
41
+ $result = $this->master_price;
42
+ } else {
43
+ $data = $this->prices()->where('user_id', \Auth::User()->id)->first();
44
+ $result = (is_null($data) ? $this->master_price : $data->price);
45
+ }
46
+ return $result;
47
+ }
48
+
49
+ public function prices()
50
+ {
51
+ return $this->hasMany(Price::class);
52
+ }
53
+
54
+ public function scopeOrderByMyPrice($query) {
55
+ if (\Auth::User()->role == 'admin') {
56
+ $query
57
+ ->select(
58
+ 'items.*', // itemsテーブルのカラム全てと
59
+ 'items.master_price AS my_price' // master_priceをmy_priceとして追加
60
+ );
61
+ }
62
+ else {
63
+ $query
64
+ ->join(\DB::raw('(SELECT item_id, price FROM prices WHERE user_id = :user_id) AS prices', ['user_id' => \Auth::User()->id]), 'prices.item_id', 'items.id') // pricesからuser_idの一致するレコードを引き出し、itemsのidと紐付ける
65
+ ->groupBy('prices.item_id') // pricesのitem_idでグルーピングすることでpricesの結合を1件に絞り込む
66
+ ->select(
67
+ 'items.*', // itemsテーブルのカラム全てと
68
+ 'COALESCE(prices.price, items.master_price) AS my_price' // joinしたpricesのpriceがあればpriceを、なければmaster_priceをmy_priceとして追加
69
+ );
70
+ }
71
+ return $query->orderBy('my_price', 'asc'); // my_price順でソート
72
+ }
73
+ }
74
+ ```
75
+ 使い方は仕様変更前と同じです。Model内の実装だけが変わります。