2022-05-29|閱讀時間 ‧ 約 3 分鐘

model關聯的失敗異常

      在練習model的關聯時,User has one Store; Store has many Products; Product has many Stores,發現Store與Product之間的關聯有異常,因為Product.new後,無法把Product的實體指定給Store,但Store確實是有save,有確實存在的。經過整理後,問題如下:
    1. p1 = Product.new(name:"衛生紙") 接著執行 p1.stores = s1 卻出現 undefined method "each"的錯誤訊息。(如下圖一)
    2. 反過來執行 s1.products = p1 也是出現 undefined method "each"的錯誤訊息。(如下圖二)
    3. 我用 s1.products.build(name:"衛生紙") 再用 s1.save去存,結果出現 Products is invalid 的錯誤訊息。(如圖三)
    4. 我用 s1.products p1 結果出現 Validation failed: Store must exist的錯誤訊息,但從最上面 Store.all可以確定Store是有存在的。 (如圖四)
    圖一
    圖一
    圖二
    圖三
    圖四

      後來依照龍哥的為自己學Ruby裡的Model關聯性單元中,依序照著老師建立model並於rails c裡執行指令,確認都正常Store與Product間都沒問題,所以確認不是windows的問題。於是比對了我的跟龍哥的schema與migration後,發現了不一樣的地方(如圖schema與圖migration)。所以可能就是因為我在建立Product model時用 store:references,產生了null:false,而老師是用store_id:integer,導致我product的store_id在nil的情況下,無法把Product.new的實體指定到store上。
    圖schema
    圖migration

    解決方法:
    1. 就是要讓Product沒有null:false的限制。
    2. 強制給實體掛上store_id:
    我們先把User / Store / Product都先建立出實體,並先把User跟Store先存好。
    u1=User.new(name:"美國")
       (0.7ms)  SELECT sqlite_version(*)

    u1.save
     TRANSACTION (0.1ms)  begin transaction
      User Create (1.0ms)  INSERT INTO "users" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "美國"], ["created_at", "2022-05-29 14:44:39.616534"], ["updated_at", "2022-05-29 14:44:39.616534"]]
      TRANSACTION (1.2ms)  commit transaction
     => true

    s1=Store.new(title:"costco")

    u1.store = s1
      Store Load (0.3ms)  SELECT "stores".* FROM "stores" WHERE "stores"."user_id" = ? LIMIT ?  [["user_id", 1], ["LIMIT", 1]]
      TRANSACTION (0.0ms)  begin transaction
      Store Create (0.9ms)  INSERT INTO "stores" ("title", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "costco"], ["user_id", 1], ["created_at", "2022-05-29 14:45:20.222725"], ["updated_at", "2022-05-29 14:45:20.222725"]]
      TRANSACTION (1.1ms)  commit transaction

    接下來處理Product:
    p1=Product.new(name:"衛生紙")

    重點來了,先把store的id塞給product:
    p1.store_id = s1.id
     => 1

    打p1確認一下

    這時可以得知,p1已經有store_id了,所以上述問題皆沒問題。
    (因為一直發布失敗,或是發布後程式碼消失,造成排版亂掉,所以就只好省略部分程式碼)
    分享至
    成為作者繼續創作的動力吧!
    紀錄並分享學習 Code 的過程~
    從 Google News 追蹤更多 vocus 的最新精選內容從 Google News 追蹤更多 vocus 的最新精選內容

    發表回應

    成為會員 後即可發表留言