เกี่ยวกับ Collection Model และ Resource Model


29

ฉันสับสนเล็กน้อยเกี่ยวกับการใช้โมเดลทรัพยากรและโมเดลการรวบรวม บางครั้งเมื่อฉันเห็นตัวอย่างสำหรับการโหลดผลิตภัณฑ์โดยใช้คุณลักษณะเฉพาะในบางตัวอย่างพวกเขาใช้โมเดลการรวบรวมและบางครั้งพวกเขาใช้โมเดลทรัพยากร

นอกจากนี้ฉันสามารถใช้วิธีการเฉพาะget...และset...พร้อมกับชื่อแถวของตารางได้เมื่อใด ชอบ,getName getIdฉันพยายามใช้ แต่ไม่สามารถรับค่าและแสดงข้อผิดพลาด: "การโทรไม่ได้กำหนดวิธีในวัตถุ"

$product = Mage::getModel('catalog/product')
    ->loadByAttribute('name', 'product_name');

echo $product->getName(); 
echo $product->getSku();

มันแสดงให้เห็น "วิธีที่ไม่ได้กำหนดgetSku()"

ถ้าฉันใช้var_dump($product)SKU จะแสดงเป็นวัตถุ แต่ไม่สามารถรับ SKU ที่ใช้getSku()...


เพื่อให้ชัดเจน - $productในตัวอย่างของคุณเป็นตัวอย่างของMage_Catalog_Model_Productซึ่งเป็น "รูปแบบ" ในวีโอไอพีสำนวน
benmarks

ใช่ถูกต้อง. แต่ฉันสับสนเมื่อต้องใช้แบบจำลองการรวบรวมและแบบจำลองทรัพยากรและวิธีการใดที่พร้อมใช้งาน อย่างที่ฉันเห็นรุ่นของคอลเลกชันนั้นมีอยู่ในโฟลเดอร์โมเดล >> โมเดลของโมดูลและทรัพยากรนั้นมีประโยชน์ในรูปแบบของทรัพยากร แต่เมื่อใดและรูปแบบใดที่จำเป็นต้องใช้ดังนั้นฉันจึงสับสนเกี่ยวกับมัน
MagentoBoy

ฉันรู้ว่าเราจำเป็นต้องใช้วิธีการที่มีอยู่ซึ่งมีอยู่ในคอลเลกชันและแหล่งข้อมูลภายนอกด้วย แต่ฉันพบปัญหาในการใช้โมเดลที่ถูกต้อง และฉันยังไม่สามารถรับผลลัพธ์จากชุดผลลัพธ์โดยใช้วิธี "รับ" หมายถึง getName () โดยใช้ชื่อแถวของตารางฐานข้อมูล มันแสดงให้เห็นถึงวิธีการที่ไม่ได้กำหนดในวัตถุหมายความว่าฉันเข้าถึงโมเดลหรือวิธีการที่ไม่ถูกต้องซึ่งฉันจำเป็นต้องใช้ดังนั้นฉันจึงไม่ได้ยืนยันว่าฉันต้องใช้อะไร
MagentoBoy

1
ขอบคุณที่ถามคำถามนี้ .. ฉันกำลังค้นหาคำตอบสำหรับคำถามนี้มานาน .. +1 ..
Elavarasan

คำตอบ:


63

โมเดล CRUD ของวีโอไอพีมีสามประเภทคลาสพื้นฐาน

"แบบจำลอง" คือสิ่งที่คุณใช้บ่อยที่สุด ข้อมูลนี้แสดงถึงประเภทของประเภทใดประเภทหนึ่งในวิธีไม่เชื่อเรื่องฐานข้อมูล (ผลิตภัณฑ์, หมวดหมู่, หน้า CMS, รีวิว ฯลฯ )

"โมเดลทรัพยากร" เป็นคลาสที่อยู่เบื้องหลังการดึงข้อมูลจริงจาก Magento ทุกโมเดลมีโมเดลรีซอร์สที่ใช้เพื่อโหลดอินสแตนซ์เดียวของโมเดลจากฐานข้อมูล

"คอลเลกชัน" เป็นคลาสที่โหลดอาร์เรย์เช่นโครงสร้างของหลายรุ่นตามชุดของกฎ WHERE clauseคิดว่ามันเหมือนของ SQL

ค่อนข้างสับสนอยู่เบื้องหลัง Magento ยังถือว่าคอลเลกชันเป็นแบบจำลองทรัพยากร ดังนั้นจึงมีรุ่นทรัพยากรคอลเลกชันและรุ่นทรัพยากรบุคคล

โดยทั่วไปเมื่อคุณต้องการโหลดเฉพาะรายการที่คุณใช้รูปแบบ เมื่อคุณต้องการโหลดจำนวนของรายการที่คุณใช้รีซอร์สโมเดลคอลเลกชัน

//loads one
$product = Mage::getModel('catalog/product')->load($id);

//loads many products where price is greater than 100
$products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*') //load all fields, see EAV below
->addAttributeToFilter('price', array('gt'=>'100'));

foreach($products as $product)
{
    var_dump($product->getSku());
}

สิ่งหนึ่งที่ต้องคำนึงถึงเกี่ยวกับการโหลดผ่านโมเดลทรัพยากรคอลเลกชันคือวิธีการของ แต่ละรุ่นafterLoadจะไม่ถูกเรียกโดยอัตโนมัติซึ่งหมายความว่าข้อมูลบางอย่างอาจไม่สามารถโหลดได้

รุ่นทรัพยากร individuaเรียนมักจะไม่เข้าถึงได้โดยตรง อย่างไรก็ตามในบางครั้งรูปแบบที่เฉพาะเจาะจงจะมีรูปแบบทรัพยากรที่มีวิธีการที่เป็นประโยชน์ สิ่งเหล่านี้คุณจะค้นพบเมื่อเวลาผ่านไปโดยใช้ระบบ

ในที่สุดก็มีอีกหนึ่งความแตกต่างที่จะทำ โมเดล CRUD ปกติของ Magento มีไวยากรณ์พิเศษสำหรับการโหลดผ่านสิ่งที่ไม่ใช่รหัสตัวเลข ตัวอย่างเช่นต่อไปนี้เป็นวิธีโหลดโมเดลหน้า CMS ตามชื่อเรื่อง

$page = Mage::getModel('cms/page')->load('Home page','title');
var_dump($page->getData());

อย่างไรก็ตาม Magento บางรุ่นเป็นรุ่น EAV นั่นหมายถึง "ค่าแอตทริบิวต์เอนทิตี" และเป็นวิธีแฟนซีในการพูดแบบจำลองเหล่านี้ไม่มีชุดของฟิลด์ที่แน่นอน ซึ่งรวมถึงรุ่นผลิตภัณฑ์และรุ่นหมวดหมู่ คุณลักษณะนี้เป็นสิ่งที่ช่วยให้คุณเลือกคุณลักษณะที่แตกต่างกันสำหรับผลิตภัณฑ์ประเภทต่างๆ แต่ละฟิลด์ในโมเดล EAV นั้นรู้จักกันในชื่อแอตทริบิวต์ ไวยากรณ์ข้างต้นไม่สามารถใช้ได้กับรุ่นเหล่านี้ แต่คุณต้องใช้loadByAttributeวิธีนี้แทน

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'n2610');

เกี่ยวกับปัญหาเฉพาะของคุณหากคุณได้รับข้อผิดพลาดด้วยข้อความ "เมธอดไม่ได้กำหนด" โดยเฉพาะแสดงว่ามีบางอย่างผิดปกติกับระบบของคุณ แม้ว่าgetSkuจะไม่มีวิธีการอยู่ แต่ Magento ก็มีวิธีตั้งค่าแบบเวทและทะเยอทะยานซึ่งทำให้มั่นใจได้ว่าการgetโทรไปที่รุ่นใด ๆจะส่งคืนบางสิ่งอยู่เสมอแม้ว่าจะเป็นโมฆะก็ตาม

มีโอกาสมากขึ้นที่คุณจะได้รับข้อผิดพลาดดังนี้

Call to a member function getSku() on a non-object

ข้อผิดพลาดนี้เกิดขึ้นเนื่องจากloadByAttributeวิธีการส่งคืนfalseหากไม่สามารถโหลดวัตถุ

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'this-is-not-a-sku');
var_dump($product); //prints false

ลองอะไรแบบนี้ในรหัสของคุณ

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'sku-value');
if($product)
{
    var_dump($product->getName());
    var_dump($product->getSku());
    var_dump($product->getData());
}
else
{
    var_dump("Could not load product");
}

นอกเหนือจากเงื่อนไขให้สังเกตgetData()วิธีการ นี่จะส่งคืนอาร์เรย์ของข้อมูลทั้งหมดของวัตถุเป็นอาร์เรย์

หวังว่านี่จะเพียงพอที่จะทำให้คุณเคลื่อนไหวได้ โชคดี!


@Alan .. คำอธิบายที่ดีมาก ... ฉันได้อ่านโพสต์ของคุณมากมายใน Magento :) .. ฉันมีความสุขมากหลังจากที่ได้เห็นการตอบกลับโพสต์ของฉัน ฉันจะก้าวไปข้างหน้าพร้อมกับข้อมูลของคุณ ถ้าฉันจะได้รับปัญหาใด ๆ ฉันหวังว่าฉันจะได้รับการสนับสนุนที่ดีจากชุมชนนี้ ในขณะที่ฉันใหม่ในวีโอไอพีและ pogramming ดังนั้นคำถามของฉันอาจไม่เป็นแนวคิดมากนัก แต่ก็ยังต้องการเรียนรู้ ฉันชอบกรอบวีโอไอพีมาก :) ขอบคุณครับ :)
MagentoBoy

ฉันขอโทษฉันมีคำถามอีกหนึ่งข้อ ถ้าฉันเรียก $ product = Mage :: getModel ('แคตตาล็อก / ผลิตภัณฑ์'); และถ้าฉันโทรหา getName () และ getSku () ฉันสามารถรับค่าได้หรือไม่ถ้าฉันย้ำผลิตภัณฑ์ $ ใน foreachloop หรือฉันต้องเรียก loadByAttribute () วิธีการ
MagentoBoy

@MagentoBoy คำขอโทษของฉัน แต่อุปสรรคทางภาษาดูเหมือนจะปกปิดคำถามของคุณ ฉันไม่แน่ใจว่าคุณกำลังถามอะไร
Alan Storm

ครับผมขอโทษ ด้วยความตื่นเต้นฉันไม่ได้แสดงคำถามของฉันอย่างชัดเจน แต่ฉันพยายามและตอนนี้ฉันสามารถรับรายการผลิตภัณฑ์และสามารถดึงผลิตภัณฑ์โดยใช้คุณลักษณะที่แตกต่างกันอย่างถูกต้อง :) และใช่คำถามของฉันคือฉันสามารถใช้รับวิธีเช่น getName (), getPrice (), getSku () โดยไม่ต้องเรียก addAttributeToSelect ('*'), addAttributeToFilter () หรือ loadByAttribute (); สำหรับอดีต $ product = Mage :: getModel ('แคตตาล็อก / ผลิตภัณฑ์'); foreach ($ product as $ p) {echo $ p-> getName (). "". $ p-> getSku ();} ... เนื่องจาก get model จะสร้างอินสแตนซ์ของคลาสผลิตภัณฑ์ขึ้นมาจากนั้นเราสามารถเข้าถึง access และ set method ได้ .
MagentoBoy

1
@ user8009 ข้อความผิดพลาดนั้นสามารถเกิดขึ้นได้ด้วยเหตุผลมากมาย หากคุณไม่สามารถเข้าถึง FTP หรือทำซ้ำปัญหาในระบบท้องถิ่น / รุ่นที่กำลังพัฒนาคุณจะไม่มีทางแก้ไขปัญหาได้
อลันสตอร์ม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.