DataMapper
هنتناول فى الموضوع التالى ORM فرض نفسه فى عالم روبى وهو
DataMapper... كنا تحدثنا عن التعامل المباشر مع قواعد البيانات من خلال SQLite, MySQL وتعرضنا بعد ذلك لل ORMs من خلال ActiveRecord
1- مامعنى ORM ؟ هى اختصار ل Object Relational Mapping حيث تقوم بتمثيل بياناتك على هيئة objects من classes بدلا من صفوف من جداول
فبإختصار الclass بيعبر عن بنية الجدول وال object بيعبر عن كل صف فى الجدول
تستطيع ايضا من خلال ال ORMs ادارة العلاقات بين الجداول وبعضها يتيح الوراثة!
هننشئ فى المثال التالى دليل تليفونات..
1- المتطلبات
require 'rubygems'
require 'dm-core'
require 'dm-validations'
2- تحديد قاعدة البيانات
DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/dmphoner.db")
هنا هنخليها فى المجلد الحالى بإسم dmphoner.db
3- اذا هتتيح عملية ال logging عشان تقدر تتبع اللى بيحصل بالظبط
DataObjects::Sqlite3.logger = DataObjects::Logger.new(STDOUT, 0)
بما اننا هنستخدم SQLite فمنطقى يكون اللlogger خاص بيها.
4- انشئ ال resource وهنا هو User
class User
include DataMapper::Resource
#properties.
property :id, Serial
property :name, String, :nullable => false, :unique => true
property :phone, Integer, :nullable => false
#validations.
validates_length :name, :minimum => 4
validates_length :phone, :is => 5
end
لاحظ property لتعريف عمود جديد
عندنا انواع بيانات كتير زى Serial -ارقام متسلسلة- ، String للنص و Integer للأرقام الصحيحة
وبعدها نقوم بتحديد خصائص العمود زى هل هو NULL ، هل هو فريد -unique-
ثم نحدد ال validations للتأكد من سلامة البيانات اللتى ستستخدم مثلا اقل طول مسموح للعمو name يكون 4
يوجد اختيارات كثيرة مثل validates_is_number للتأكد من انها رقم ، و validates_length للتأكد من الطول يساوى رقم ما او فى مدى معين
validates_is_unique للتأكد من "التفرد" وللمزيد راجع
http://datamapper.org/doku.php?id=docs:validations 5- migrate!
لإنشاء الجدول.. اذا عندك اكتر من صف بيرث Resource تقدر تستدعى DataMapper.migrate! لتقوم بإنشاءهم جميعا.
طبعا يستحسن انك تختبر هل قاعدة البيانات موجودة اول شئ او لأ
CRUD!
6- بعض الدوال للمعالجة
1- لإضافة مستخدم
هنحتاج ننشئ كائن من الصف User ودى معناها صف جديد فى الجدول..
هنحتاج نحدد صفاته "الأعمدة" وهنا عن طريق attributes بنمرر قاموس بالصفات وقيمها.
def add_user(uname, uphone=12345)
u=User.new
u.attributes={:name => uname, :phone => uphone}
u.save!
end
2- للحصول على مستخدم ما تقدر تستخدم الطريقة first للحصول على اول ظهور للصف الذى يحوى العمود name قيمته uname
def get_user(uname)
return User.first(:name => uname)
end
3- لحذف مستخدم ما بالإسم.. اولا نحصل على المستخدم ونستدعى الطريقة destroy لحذفه
def delete_user(uname)
begin
user=get_user(uname)
user.destroy
rescue Exception => ex
puts ex # undefiend method 'destroy' for nil:NilClass.
end
end
4- لتحديث مستخدم ما.. اولا نحصل على المستخدم بالطريقة get_user ونحدد قيمة التليفون الجديدة "نعم بتعديلها فى قاموس ممرر ل attributes=
ونقوم بحفظه بالطريقة save!
def update_user(uname, new_phone)
begin
user=get_user(uname)
user.attributes={:phone => new_phone}
user.save!
rescue
end
end
5- لعرض كل الصفوف.. نقوم بالحصول على كل الكائنات"الصفوف" بإستخدام الطريقة all ثم نقوم بعرضهم كالمعتاد..
def view_all
puts "---------Users--------"
User.all.each do |u|
puts u.name + " => " + u.phone.to_s
end
#p User.all
end
مجرد مجموعة من البيانات المزيفة عشان الجدول

def fake_list
recs=[['mido', 12323], ['john', 63874], ['ahmed adel', 14785] ]
recs.each do |name, phone|
add_user(name, phone)
end
end
العلاقاتهنشوف ازاى نقدر نظبط العلاقات بين الجداول فى المثال التالى مثلا عندنا مستخدم وليه عدد ما من المواضيع وفى نفس الوقت اى موضوع هيبقة بينتمى لمستخدم واحد فقط
يبقة كدا
user
HAS_MANY topics
topic
BELONGS_TO user
هنتعامل مع قاعدة dmboard.db
جميل..
1- نعرف ال Models “الclasses” اللى بتمثل الجداول فى قاعدة البيانات ونحدد العلاقات بإستخدام has n و belongs_to كما ذكرنا.
class Topic
include DataMapper::Resource
property :id, Serial
property :title, String
property :body, Text
belongs_to :user
#validations.
end
class User
include DataMapper::Resource
property :id, Serial
property :screen_name, String, :nullable => false
property :email, String
has n, :topics
#validations...
end
2- ننشئ الجداول
3- بعض الدوال المساعدة
لإضافة مستخدم ما..
def add_user(name, email)
begin
u=User.new
u.attributes={:screen_name => name, :email => email}
topicsarr=[ ["hello",'hello world from dm!'], ['test', 'this is a test!'], ['new tutorial!', 'this is a DM tut'] ]
rndtopic1=topicsarr.choice
rndtopic2=topicsarr.choice
t1=u.topics.build(:title => rndtopic1[0], :body => rndtopic1[1])
t2=u.topics.build(:title => rndtopic2[0], :body => rndtopic2[1])
#puts t
t1.save!
u.topics << t1
t2.save!
u.topics << t2
u.save!
rescue Exception => ex
puts ex
end
end
بنحصل على موضوع عشوائى بإستخدام choice “ميثود تابعة لل Array object”
rndtopic1=topicsarr.choice
نقوم بإنشاء الموضوع وتحديد قيم الصفات "الأعمدة" بإستخدام build
t1=u.topics.build(:title => rndtopic1[0], :body => rndtopic1[1])
نقوم بحفظها وإضافتها لمواضيع المستخدم
اخيرا حفظ المستخدم
لإنشاء بيانات اولية لجدول المستخدمين
def create_users
recs=[ ['ahmed', 'mido@yahoo.com'], ['wael', 'wael@gamil.com'], ['smsm', 'smsm@live.com'], ['jack', 'jacko@live.com'] ]
recs.each do |name, email|
add_user(name, email)
end
end
استعراض المستخدمين والمواضيع الخاص بكل منهم..
def view_all
puts "---------Users--------"
User.all(:order => [:screen_name.asc]).each do |u|
puts u.screen_name + " => " + u.email
#puts "\tTopics: #{u.topics}"
topics = Topic.all('user.screen_name' => u.screen_name)
puts "\tTopics:"
topics.each do |topic|
puts "\t\t#{topic.title} => #{topic.body}"
end
end
end
هنا نحصل على كل المواضيع اللتى كتبها مستخدم بإسم u.screen_name
topics = Topic.all('user.screen_name' => u.screen_name)
ونقوم بطباعة عنوان ومحتوى كل موضوع
topics.each do |topic|
puts "\t\t#{topic.title} => #{topic.body}"
end
الى اين ؟مرجعك الأول والرئيسى هو الوثائق الرسمية
http://datamapper.org/doku.phpوالى لقاء قادم