Programming Freaks  | دورات ومقالات برمجيه

Please login or register.

Login with username, password and session length
Advanced search  

News:

Programming-Fr34ks.net
Up and running

Author Topic: DataMapper Tutorial  (Read 888 times)

Striky

  • Helping Freak
  • Administrator
  • Posting Freak
  • *****
  • Posts: 252
    • View Profile
    • WWW
    • Email
DataMapper Tutorial
« on: March 08, 2009, 09:13:34 PM »

DataMapper


هنتناول فى الموضوع التالى ORM فرض نفسه فى عالم روبى وهو DataMapper... كنا تحدثنا عن التعامل المباشر مع قواعد البيانات من خلال SQLite, MySQL وتعرضنا بعد ذلك لل ORMs من خلال ActiveRecord

1- مامعنى ORM ؟ هى اختصار ل Object Relational Mapping حيث تقوم بتمثيل بياناتك على هيئة objects من classes بدلا من صفوف من جداول
فبإختصار الclass بيعبر عن بنية الجدول وال object بيعبر عن كل صف فى الجدول
تستطيع ايضا من خلال ال ORMs ادارة العلاقات بين الجداول وبعضها يتيح الوراثة!

هننشئ فى المثال التالى دليل تليفونات..
1- المتطلبات
Code: [Select]
require 'rubygems' 
require 'dm-core'
require 'dm-validations'


2- تحديد قاعدة البيانات
Code: [Select]
DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/dmphoner.db") 

هنا هنخليها فى المجلد الحالى بإسم dmphoner.db

3- اذا هتتيح عملية ال logging عشان تقدر تتبع اللى بيحصل بالظبط
Code: [Select]
DataObjects::Sqlite3.logger = DataObjects::Logger.new(STDOUT, 0) 

بما اننا هنستخدم SQLite فمنطقى يكون اللlogger خاص بيها.

4- انشئ ال resource وهنا هو User
Code: [Select]
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!
Code: [Select]
User.auto_migrate! 

لإنشاء الجدول.. اذا عندك اكتر من صف بيرث Resource تقدر تستدعى DataMapper.migrate! لتقوم بإنشاءهم جميعا.
طبعا يستحسن انك تختبر هل قاعدة البيانات موجودة اول شئ او لأ



CRUD!
6- بعض الدوال للمعالجة

1- لإضافة مستخدم
هنحتاج ننشئ كائن من الصف User ودى معناها صف جديد فى الجدول..
هنحتاج نحدد صفاته "الأعمدة" وهنا عن طريق attributes بنمرر قاموس بالصفات وقيمها.
Code: [Select]
def add_user(uname, uphone=12345) 
   u=User.new
   u.attributes={:name => uname, :phone => uphone}
   u.save!
end 


2- للحصول على مستخدم ما تقدر تستخدم الطريقة first للحصول على اول ظهور للصف الذى يحوى العمود name قيمته uname
Code: [Select]
def get_user(uname) 
    return User.first(:name => uname)
end
 

3- لحذف مستخدم ما بالإسم.. اولا نحصل على المستخدم ونستدعى الطريقة destroy لحذفه
Code: [Select]
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!
Code: [Select]
 def update_user(uname, new_phone) 
    begin
        user=get_user(uname)
        user.attributes={:phone => new_phone}
        user.save!
    rescue
   
    end
end

5- لعرض كل الصفوف.. نقوم بالحصول على كل الكائنات"الصفوف" بإستخدام الطريقة all ثم نقوم بعرضهم كالمعتاد..
Code: [Select]
def view_all 
    puts "---------Users--------"
    User.all.each do |u|
        puts u.name + " => " + u.phone.to_s
    end
  #p User.all
end 


مجرد مجموعة من البيانات المزيفة عشان الجدول :)
Code: [Select]
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 كما ذكرنا.
Code: [Select]
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- ننشئ الجداول
Code: [Select]
DataMapper.auto_migrate! 


3- بعض الدوال المساعدة
لإضافة مستخدم ما..
Code: [Select]
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”
Code: [Select]
    rndtopic1=topicsarr.choice 
نقوم بإنشاء الموضوع وتحديد قيم الصفات "الأعمدة" بإستخدام build
Code: [Select]
    t1=u.topics.build(:title => rndtopic1[0], :body => rndtopic1[1]) 

نقوم بحفظها وإضافتها لمواضيع المستخدم
Code: [Select]
u.topics << t1 


اخيرا حفظ المستخدم
Code: [Select]
    u.save! 


لإنشاء بيانات اولية لجدول المستخدمين
Code: [Select]
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


استعراض المستخدمين والمواضيع الخاص بكل منهم..
Code: [Select]
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
Code: [Select]
        topics = Topic.all('user.screen_name' => u.screen_name) 

ونقوم بطباعة عنوان ومحتوى كل موضوع
Code: [Select]
        topics.each do |topic|
          puts "\t\t#{topic.title} => #{topic.body}"
        end

الى اين ؟

مرجعك الأول والرئيسى هو الوثائق الرسمية
http://datamapper.org/doku.php

والى لقاء قادم
« Last Edit: March 09, 2009, 03:24:40 AM by Ahmed Youssef »
Logged

Life is just a chance to grow a soul. - A. Powell
Weblog: http://ahmedyoussef.wordpress.com/