Skip to main content

چند سال پیش، این وبسایت راه‌اندازی شد تا محلی برای افرادی باشد که در پی یادگیری زبان برنامه‌نویسی روبی هستند. متاسفانه، از آنجایی که در دنیای امروز، روبی تقریبا جایگاه خود برای توسعه نرم‌افزارهای پردازش متن را از دست داده و بیشتر به عنوان زبانی برای توسعه وب و همچنین مدیریت سیستم شناخته می‌شود، استقبال خوبی از این وبسایت نشد چرا که تمرکزی روی توسعه وب با روبی نداشتیم و همچنین به ابزارهایی مانند chef که برای مدیریت سیستم به کار می‌روند، نپرداختیم.

پس از مدت نسبتا طولانی، حالا قرار است این وبسایت محلی باشد برای این که افراد بتوانند کارکرد روبی در راه‌‌اندازی یک کسب و کار اینترنتی را فرا بگیرند. در سلسله مطالب جدید وبسایت، قرار است که جوانب مختلف یک کسب و کار اینترنتی را بررسی کرده و سپس شروع به توسعه وبسایت آن با روبی آن ریلز کنیم.

روبی آن ریلز برای کسب و کار - قسمت اولچرا روبی آن ریلز؟

روبی آن ریلز (به انگلیسی: Ruby On Rails) که به اختصار به آن ریلز هم گفته می‌شود (و جهت اطلاعات بیشتر می‌توانید به وبسایت آن مراجعه کنید) یک چارچوب (framework) برای توسعه نرم‌افزارهای مبتنی بر وب با زبان روبی است که در سال ۲۰۰۵ توسط شخص «دیوید هاینمایر هنسون» (به انگلیسی: David Heinmier Hansson) که به نام DHH نیز شناخته می‌شود، در حاشیه ایجاد کمپانی Basecamp ارائه شد.

در واقع شخص DHH به هنگامی که در حال کار بر روی بیس‌کمپ بود، چارچوبی که بیس‌کمپ را به یک نرم‌افزار قابل اجرا در محیط وب تبدیل می‌کرد را به صورت جداگانه و به صورت آزاد و متن‌باز (با مجوز MIT) به جهان عرضه کرد. این چارچوب در واقع معماری MVC را به جهان معرفی می‌کرد (که در این مطلب می‌توانید پیرامون آن بخوانید و در این مطلب نیز با مزایا و معایب آن آشنا شوید.) و همین امر باعث شد افراد زیادی، ترجیح دهند که کسب و کارها و نرم‌افزارهای اینترنتی خود را مبتنی بر ریلز ارائه کنند.

در سال ۲۰۰۶ نخستین نسخه‌های شبکه اجتماعی توییتر و پس از آن وبسایت‌هایی چون گیت‌هاب و کسب و کارهایی چون Shopify و AirBnB نیز به استفاده از این چارچوب روی آوردند و هجوم جامعه استارتاپی سیلیکون ولی به ریلز به عنوان چارچوبی برای توسعه،  توسعه‌دهندگان دیگری مانند تایلر اوتول (سازنده فرمورک لاراول) را برانگیخت تا مفاهیم MVC را در زبان‌های دیگر نیز پیاده‌سازی کنند.

از آنجایی که این وبسایت نیز با هدف گردهمایی توسعه‌دهندگان روبی ایجاد شده است، تصمیم شد تا فرایند توسعه کسب و کار اینترنتی با استفاده از این فرمورک بررسی شود.

روبی آن ریلز برای کسب و کار - قسمت اول

پروسه سلسله مقالات «روبی آن ریلز برای کسب و کار»

در این سلسله مقالات، ما پروسه ایجاد یک کسب و کار را بررسی خواهیم کرد. البته توجه داشته باشید که این موضوع اصلا و ابدا به این معنا نیست که قرار است آموزش‌ها، رنگ و بوی استارتاپی داشته باشد. ما در این سلسله مقالات، فرض را بر آشنایی پیشین شما با کسب و کارهای اینترنتی و استارتاپ‌ها گذاشته‌ایم و صرفا قرار است که در این مقالات، شما را با نحوه پیاده‌سازی آشنا کنیم.

برای این مقالات، بخش‌های مختلفی در نظر گرفته شده است که در ادامه با آن‌ها آشنا می‌شویم:

استارتاپ در هفت روز

استارتاپ در هفت روز، نام کتابی است به قلم دن نوریس که در آن، داستان ایجاد کسب و کار خود در هفت روز را توضیح می‌دهد. البته ما قرار نیست در هفت روز همه‌چیز را به نتیجه برسانیم، اما قرار است از آموزش‌های این کتاب بهره لازم و کافی را به جهت ایجاد یک کسب و کار اینترنتی ببریم.

در این کتاب، تقریبا تمامی مفاهیم مرتبط با استارتاپ به خلاصه‌ترین شکل ممکن توضیح داده شده است. به همین خاطر، این کتاب به عنوان الگوی این سلسله مقالات انتخاب شد. اگرچه توصیه شخصی نگارنده این است که اگر آشنایی لازم و کافی با استارتاپ‌ها را ندارید، بهتر از است از کتاب‌هایی مانند Lean Startup (نوپای ناب) آغاز کنید و سپس به سراغ کتاب‌های آموزش سریع بروید.

پیاده‌سازی محصول کمینه ارزشمند (MVP) با MVC در ریلز

پس از آن که یاد گرفتیم که چطور می‌توانیم کسب و کار خود را راه‌اندازی کنیم و طرحی برای کسب و کار خود آماده کردیم، لازم است تا پیاده‌سازی MVP خود را آغاز کنیم. در ابتدا قرار است که MVC را بررسی کنیم و یک MVP بسیار ساده با آن ایجاد کنیم. این مرحله، صرفا برای آشنایی ما با روبی آن ریلز خواهد بود.

پیاده‌سازی محصول کمینه ارزشمند با REST

در دنیای امروز عمده وبسایت‌ها و سرویس‌های اینترنتی، از معماری REST استفاده می‌کنند. ما پس از آن که به قدر کافی با ریلز آشنا شدیم، به این معماری مهاجرت می‌کنیم تا محصول خود را به استانداردهای بازار شبیه‌تر کنیم. البته باید توجه کنید که پس از این که MVP خود را با معماری REST پیاده‌سازی کنیم، نیاز خواهیم داشت تا بخش front-end آن را نیز  طراحی کنیم.

پیاده‌سازی front-end

در این بخش، قرار است که یاد بگیریم چطور می‌توانیم یک front-end زیبا برای وبسایت خود طراحی کنیم. در بسیاری از آموزش‌ها از چارچوب‌ها و کتابخانه‌هایی چون next, nuxt, react یا vue استفاده می‌شود، اما به احتمال بسیار زیاد، ما از Svelte استفاده خواهیم کرد. یکی از دلایل انتخاب Svelte نیز سادگی فراگیری آن است.

استقرار MVP روی سرور و ارائه آن به جهان بیرون

در نهایت، پس از پیاده‌سازی MVP و تست کردن آن روی سیستم محلی (Local) نوبتی هم باشد، نوبت انجام مراحل Dev Ops یا استقرار و توسعه عملیات است (چنانچه با DevOps آشنایی ندارید توصیه می‌شود این مطلب را مطالعه کنید). پس از آن که back-end و front-end را ساختیم، آن‌ها رو روی یک یا چند سرور قرار داده، دامنه‌ای برایشان انتخاب می‌کنیم و سپس دامنه را به سرور خود متصل کرده، پیکربندی‌های وب‌سرور را انجام می‌دهیم و به این شکل، یک کسب و کار اینترنتی داریم.

روبی آن ریلز برای کسب و کار - قسمت اول

سخن آخر

این سلسله مقالات گرچه ممکن است بخش خوبی از ایجاد و برپاسازی یک کسب و کار اینترنتی را برای شما روشن کند، اما همه مسیر نخواهد بود. توصیه شخصی نگارنده، این است که پس از خواندن هر قسمت، خودتان نیز مفاهیم و اصطلاحاتی که در مقالات مطرح می‌شوند را جست و جو و بررسی کنید و دانش خود را پیرامون کسب و کارهای اینترنتی محک بزنید.

همچنین، امید است که نوشتن این سلسله مقالات، باعث شود افراد بیشتری برای خود شغل ایجاد کنند و در شرایط اقتصادی فعلی، بتوانند با استفاده از دانش، هنر و محصولات خود؛ کسب درآمد کنند.

موفق باشید.

احتمالا این روزها با داغ بودن بحث بلاک‌چین و بیت‌کوین و سایر مباحث مرتبط با رمزارزها، احتمالا اگر عمیق‌تر از سایرین وارد ماجرای مرتبط با رمزارز شده باشید، متوجه شدید که یکی از مهم‌ترین بخش‌های تعاریف مرتبط با رمزارز، الگوریتمی به نام «اثبات کار» یا Proof of work است.

در واقع، اگر بخواهیم با دید زندگی واقعی به این الگوریتم نگاه کنیم به این شکل نگاه خواهیم کرد :

یک معلم، تا وقتی شما پاسخ سوال رو به درستی ننوشته باشید نمره‌ای به شما نمیده.

در واقع، شما وقتی پاسختون رو روی برگه امتحانی می‌نویسید، دارید «کار» انجام می‌دید و اگر جواب شما «درست» باشه، «پاداش» می‌گیرید. کار شما اینجا فعالیت فکری و نوشتن پاسخ درست سوال و پاداش شما، نمره (و احتمالا امکان اخذ درس بعدی) است.

در دنیای رمزارزها هم در واقع ما منابع پردازشی خودمون رو در اختیار یک سیستم بزرگتر میذاریم و در ازای کاری که داریم انجام میدیم پاداش می‌گیریم (که این پاداش، میتونه بیت‌کوین باشه).

اثبات کار در رمزارز چطور کار می‌کنه؟

در رمزارزهای مختلف معمولا روش های متفاوت و مختلفی برای اثبات کار استفاده میشه. اما اجازه بدید کمی بهتر در این باره صحبت کنیم.

یک مثال خیلی ساده رو در نظر بگیریم :

رشته های مختلفی در یک سرور وجود دارند که به صورت متن خالص (plain text) نوشته شدند. ما میخواهیم شما این ها رو طوری hash کنید که پنج رقم ابتدای هش، حتما 1a1b0 باشه.

اگر نمی‌دونید هش چیه، ویدئوهای جادی (قسمت اول، قسمت دوم، قسمت سوم) می‌تونه در درک هش به شما کمک کنه.

حالا ما باید چه کنیم؟ ابتدا باید بیایم و رشته رو هش کنیم و پنج رقم ابتدای اون رو، بررسی کنیم. اگر با این چیزی که ما در نظر داریم (و ازمون سوال شده)، تضادی داشت، تغییری درش بدیم و بعد دوباره هش کنیم و باز بررسی کنیم. همینطور بررسی رو ادامه بدیم تا برسیم به یک هش که اون چیزی که سوال ازمون خواسته رو در خودش داره و خب، جایزه‌ش رو بگیریم.

اصلا پیچیده نیست، اما این که دقیقا چه میشه کرد که این اتفاق بیفته، راه‌های مختلفی داره. ساده ترین راه حلش رو قراره با هم در ادامه پیاده کنیم.

پیاده سازی در روبی

هش کردن در روبی

برای هش کردن داده‌ها در روبی، از کتابخانه digest استفاده می‌کنیم. برای استفاده از این کتابخانه، شما نیازی ندارید تا جم یا افزونه خاصی نصب کنید. چرا که همراه خود روبی نصب میشه. فقط کافیه در کدتون این کار رو کنید :

require 'digest'

و سپس برای دریافت هش مورد نظر (در این مطلب از sha256 استفاده خواهیم کرد) کافیه که چنین کاری کنیم :

hash = Digest::SHA256.hexdigest("Hello, world!")
 
puts hash

و پاسخ ما چنین خواهد بود :

315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3

و اما بریم سراغ همون ساده ترین راه حلی که داشتیم، این راه حل بعنوان یک راه حل ساده، به ذهن من رسید. راه حل اینه :

یک عدد در نظر بگیر، اون رو به یک رشته متنی تبدیل کن، اون رو بچسبون به رشته‌ای که روی سرور بوده. تا وقتی هم که پنج رقم اول هش، اونی که من میگم نشده، این کار رو ادامه بده.

خب کد ما در نهایت چنین چیزی میشه :

########
# POW in Ruby 
########
 
require 'digest'
 
i = 0 
while true
    i = i + 1 
    string = "Sample Text" + i.to_s 
    hash = Digest::SHA256.hexdigest(string)
 
    if hash[0..4] == "1a1b0" 
 
        puts "--------"
        puts "Work proven. You worked so hard :)"
        puts "The result is #{string} and the hash is #{hash}"
        break 
 
    else 
        puts "We are at attempt No. #{i}"
    end  
 
end

اینجا اومدیم یک i تعریف کردیم. بعد یک حلقه بی‌نهایت. در حلقه، گفتیم که ما این رشته رو داریم، هر بار که حلقه اجرا میشه یک عدد به تهش اضافه می‌کنیم و در اون if داریم بررسی می‌کنیم که آیا اون پنج رقم ابتدایی، همونایین که ما می‌خواهیم؟ اگر آره حلقه متوقف بشه. اگر نه، حلقه ادامه پیدا کنه و به کاربر هم اطلاع بده که در تلاش چندم، این اتفاق افتاده. بخشی از پاسخ این برنامه رو می‌تونید اینجا ببینید :

We are at attempt No. 751270
We are at attempt No. 751271
We are at attempt No. 751272
--------
Work proven. You worked so hard :)
The result is Sample Text751273 and the hash is 1a1b0ae39e178300c5ae7650d9c809da499eb165f7e621b70c0634d673874b5d

همونطور که می‌بینید بعد از ۷۵۱۲۷۳ تلاش، تونسته اون چیزی که ما مد نظر داریم رو برامون بسازه.

این تمرین خوبیه. ولی برای کار واقعی خوب نیست. چرا؟

چیزی که پیاده شده، علیرغم این که کار میکنه و خوبه؛ از نظر پیچیدگی زمانی مشکل داره. در واقع، تمام این پیچیدگی باعث شده شدیدا به سخت‌افزار خوب و سریع؛ وابسته باشه. در صورتی که معمولا الگوریتم‌های درست و حسابی هرقدر هم لاینحل باشن، به همین سادگی‌ها نباید استقلالشون از سخت افزار رو از دست بدن. نتیجتا علیرغم این که یک طرح مفهومی خوب برای نشون دادن POW محسوب میشه، اصلا برای اجرا روی پروژه‌های جدی که نیاز به اثبات کار دارند، مناسب نیست.

در پایان هم امیدوارم که این آموزش، به دردتون خورده باشه. راستی شما برای اثبات کار چه می‌کنید؟ در بخش نظرات منتظرتونیم 🙂

به تازگی یک سرویس PaaS (یا Platform as a Service ) ایرانی به نام فندق (لینک) راه اندازی شده است که بر اساس داکر کار می‌کند، در این آموزش، قرار است که یک اپلیکیشن ساده سیناترا نوشته و سپس توسط فندق آن را دیپلوی کنیم.

راه اندازی فندق

ابتدا، باید در وبسایت فندق ثبت نام کنید، سپس ابزار خط‌فرمان آن را توسط pip نصب نمایید :

pip install fandogh-cli --upgrade

سپس، باید در فندق، لاگین کنیم :

fandogh --login --username=USERNAME --password=PASSWORD

اکنون، میتوانیم به ساخت اپلیکیشن ساده خود بپردازیم.

ساخت اپلیکشن

اکنون یک سناریوی ساده را پیاده‌سازی خواهیم کرد. در ابتدا، یک ‌Gemfile ساخته و این خطوط را اضافه میکنیم :

source 'https://rubygems.org'
 
gem 'sinatra'

سپس، یک فایل با نام app.rb باز می‌کنیم. دقت کنید سناریویی که قرار است پیاده سازی کنیم؛ بسیار ساده‌است. ما یک برنامه ساده مینویسیم که یک پارامتر را از کاربر گرفته، سپس رشته برعکس شده را در خروجی نشان دهد.

کد برنامه به شکل زیر خواهد بود :

require 'sinatra'
 
set :bind, '0.0.0.0'
 
get '/:par' do
 
 params[:par].reverse
 
end

اکنون، پروژه را ذخیره کرده و سپس، باید یک Dockerfile برای پروژه خودمان بنویسیم.

نوشتن داکرفایل

داکرفایل، به ما کمک می‌کند تا یک تصویر، با آن شرایطی که نیاز داریم ساخته شود. قبل از نوشتن داکرفایل، الزامیست تا دستور زیر را اجرا کنیم :

bundle install

تا Gemfile.lock ساخته شود. سپس، از نسخه روبی خود مطلع می‌شویم (در اینجا 2.4 ) و سپس اقدام به نوشتن داکرفایل می‌کنیم :

FROM ruby:2.4-onbuild
 
RUN mkdir -pv /usr/src/app
ADD . /usr/src/app
WORKDIR /usr/src/app 
 
CMD ["ruby", "/usr/src/app/app.rb"]

حال، باید فایل های خود را، توسط ابزار خط فرمان فندق، دیپلوی کنیم.

دیپلوی کردن پروژه توسط فندق

اکنون، کافیست با استفاده از دستورات پایه فندق، عمل دیپلوی را انجام دهیم. لازم است ابتدا یک تصویر بسازیم :

fandogh image init --name=string_reverse

پس از اجرای این دستور، شما پیامی مبنی بر موفقیت آمیز بودن ساخت تصویر، دریافت خواهید کرد. سپس، این دستور را وارد می‌کنیم :

fandogh image publish --version 0.0.1

پس از اجرای این دستور، تصویر مورد نظر شما ساخته می‌شود. پس از این که تصویر ساخته شد، میتوانیم با این دستور، آن را روی سرویس فندق؛ میزبانی کنیم.

fandogh service deploy --version 0.0.2 -p 4567

توجه داشته باشید که پس از اجرای این دستور، نام سرویس از شما پرسیده خواهد شد.

سرویسی که در این مطلب تولید کردیم، در این آدرس : stringreverse-haghiri75.fandogh.cloud در دسترس است. شما میتوانید با اجرای دستور زیر، یک رشته را برعکس تحویل بگیرید :

curl http://stringreverse-haghiri75.fandogh.cloud/salam

مطالعه بیشتر

در این مطلب، سرویس ساده‌ای مد نظر داشتیم که دیتابیس نداشت و نیازی هم به پیاده سازی دیتابیس و اسکریپت نویسی برای ارتباط با آن نداشتیم. در مطالب آینده، سعی خواهیم کرد که این موضوع نیز پوشش داده شود. همچنین، برای آشنایی بیشتر با فندق، میتوانید مستندات این سیستم (لینک) را مطالعه فرمایید.

در قسمت دوم، یاد گرفتیم که چطور پیج هایی که ساختیم رو نمایش بدیم! در این قسمت، میخوایم مستقیما با دیتابیس وارد مذاکره بشیم! در واقع در این قسمت میخوایم به کاربر اجازه بدیم که خودش یک پیج ایجاد کنه. خیلی هم شیک و ساده. ابتدا این قسمت رو به main.rb اضافه کنید :

get '/pages/new' do
	@page = Page.new
	erb :new
end

در اینجا، گفته شده که یک صفحه به اسم new.erb خونده و نمایش داده بشه. علاوه بر اون، گفتیم که از کلاس Page هم یک شیء جدید برامون بسازه. حالا، فایل new.erb رو به این شکل ایجاد کنید :

<h1> New Page </h1>
 
<form action="/pages" method="post">
	<h2> Title: </h2>
	<input type="text" name="page[title]">
	<h2> Text: </h2>
	<textarea name="page[text]" cols="50" rows="5">
	</textarea>
	<br/>
	<input type="submit">
</form>

در اینجا یک فرم ایجاد کردیم که با متد POST کار میکنه. قبل تر، در مورد متد پست توضیح دادیم، و میتونید این مطلب رو در موردش بخونید تا درکش کنید!

بسیار خوب، الان برای این که برنامه ما درست و حسابی کار کنه، فقط نیاز داریم که با یک متد POST بهش بفهمونیم که اطلاعات رو توی دیتابیس بنویسه. و خب این قسمت رو به main.rb مون اضافه میکنیم :

post '/pages' do
	page = Page.create(params[:page])
	redirect to("/pages/#{page.id}")
end

خب، در اینجا میگیم که پیجی با پارامتر هایی که داده شده بساز، و بعدش برگرد به همون پیج. به همین سادگی!

جمع بندی

در کل این سه قسمت آموزش، یک CMS بسیار ساده ساختیم که یه ادیتور داشت و میتونست نوشته های ما رو توی یک دیتابیس ذخیره کنه و بعد به ما نشون بده. کل فایل main.rb ما به این شکل در اومد :

require 'sinatra'
require 'mongoid'
 
configure do
	Mongoid.load!("./database.yml")
end
 
class Page
	include Mongoid::Document 
	field :title, type: String
	field :text,  type: String
end
 
 
get '/pages' do
	@pages = Page.all
	@title = "Page List"
	erb :index
end
 
get '/pages/new' do
	@page = Page.new
	erb :new
end
 
post '/pages' do
	page = Page.create(params[:page])
	redirect to("/pages/#{page.id}")
end
 
get '/pages/:id' do
	@page = Page.find(params[:id])
	@title = @page.title
	erb :show
end

و کل ساختار فولدرهای ما به این شکل در اومد :

simple-cms/
├── database.yml
├── main.rb
├── README.md
└── views
    ├── index.erb
    ├── new.erb
    └── show.erb

با استفاده از چنین الگویی، شما قادرید که برنامه های واقعی تری بنویسید و از اونها در دنیای واقعی استفاده کنید. در قسمت اول ذکر شد که این CMS بدرد وبلاگ و وبسایت و … نمیخوره. دلیلشم مشخصه! توی این برنامه هیچگونه پرمیشن و سشن و … ای رعایت نشده که بدونیم کدوم یوزر میتونه پیج ایجاد کنه کدوم نمیتونه و این قضایا. یعنی امنیت نداره کانتنتی که روی اون وبسایت تولید میشه. شما میتونید با خوندن داکیومنت در مورد session ها این مورد رو هم هندل کنید و CMS کامل تری بسازید!

موفق باشید 🙂

در قسمت قبل، یاد گرفتیم که چگونه یک سیستم مدیریت محتوای کوچولو رو با پایگاه داده هاش، ایجاد کنیم. در این قسمت، نمایش محتوای پیج در لینک اختصاصی و همچنین نمایش لینک ها در صفحه اصلی رو بررسی میکنیم.

آموزش این قسمت، کوتاه تر از دفعات پیش هستش، دلیلشم اینه که در بخش آخر، باید متد POST رو بررسی کنیم (اگرچه در مقاله ای قبلا این کار رو کردیم، اما میخوایم دوباره آموزش تکرار بشه و یه استفاده عملی از این موضوع داشته باشیم).

بسیار خوب، فایل index.erb که صفحات ما رو نشون میداد باز کنید، به این شکل تغییرش بدید :

<h1> Pages </h1>
<% if @pages.any? %>
<p>
<%  @pages.each do |page| %>
<a href="/pages/<%= page.id %>">
<h1><%= page.title %> </h1>
</a>
<p> <%= page.text %> </p>
<% end %>
</p>
<% else %>
<h1> No pages added! </h1>
<% end %>

دقت کردید؟ ما از id صفحات برای تولید لینک به اون ها استفاده میکنیم!

حالا بیاید کمی فکر کنیم، وقتی روی این لینک ها کلیک کنیم چه اتفاقی میفته؟ طبیعتا یه ارور ۴۰۴ به ما نشون داده میشه و به ما گفته میشه که صفحه یافت نشده. معمولا سیناترا به صورت پیشفرض یک راهنمایی کوچک هم میکنه که چه چیزی باید به فایل main.rb و … اضافه کنیم تا بتونیم نتیجه درستی بگیریم.

حالا برای این که لینک ها ما رو به جای درستی راهنمایی کنند، کافیه که فایل main.rb رو باز کنیم و این خطوط رو بهش اضافه کنیم :

get '/pages/:id' do
	@page = Page.find(params[:id])
	@title = @page.title
	erb :show
end

خب توی این کد، میگیم که پیج ها رو بر اساس id شون پیدا کنه، و تیتر صفحه رو هم تیتر پیج ایجاد شده بذاره. و در نهایت هم میگیم که ظاهر برنامه در show.erb هست. حالا، نیاز داریم که یک show.erb هم بنویسیم :

<h1><%= @page.title %> </h1>
<p>
<%= @page.text %>
</p>
<a href="/pages"> Back to main page </a>

اینجا، عنوان و متن صفحه رو نشون دادیم، به صفحه اصلی هم که لیست مطالبمون داخلش قرار داره هم لینک کردیم. در آموزش بعدی، سعی میکنیم یه ادیتور بسازیم و بتونیم یک صفحه جدید رو از طریق مرورگر، به CMSمون اضافه کنیم!

توی این نوشته، قصد و هدف اینه که بیایم و با استفاده از فرمورک Sinatra و دیتابیس غیررابطه ای MongoDB ، یک سیستم مدیریت محتوای کوچیک بنویسیم.


دقت کنید که این CMS صرفا یک کار آموزشی بوده و برای استفاده به عنوان CMS اصلی وبلاگ/وبسایت شما به هیچ وجه مناسب نیست

بسیار خوب، برای این که بدونیم از کجا شروع کنیم، ابتدا بیایم ببینیم که از چه چیزهایی قراره که استفاده بشه :

  1. فرمورک سیناترا
  2. ارتباط دهنده شیء – مستند (ODM) برای Mongo (اینجا از Mongoid استفاده میکنیم).

خب، ابتدا بیایم Gemfile رو بنویسیم :

source 'https://rubygems.org'
 
gem 'sinatra'
gem 'mongoid'

بسته به نیازتون، میتونید جم های دیگری هم بهش اضافه کنید.

حالا، باید به برنامه بفهمونیم که دیتابیس ما چه ویژگی هایی باید داشته باشه، پس یک فایل database.yml ایجاد میکنیم و این ها رودرونش مینویسیم :

development:
 clients:
  default:
   database: myCMS
   hosts:
    - localhost:27017
 production:
  clients:
   default:
    uri: <%= ENV['MONGOHQ<em>URL'] %>
    options:
     skip_version_check: true
safe: true

حالا دو مرحله اساسی کارمون انجام شده، هم میدونیم که دیتابیس چه ویژگی هایی داره و هم میدونیم که چه چیزهایی برای درست اجرا شدن برناممون نیازه.

حالا، وقتش رسیده که یک برنامه ساده بنویسیم:

require 'sinatra' 
require 'mongoid'
 
configure do
	Mongoid.load!("./database.yml")
end

این رو در فایلی به اسم main.rb نوشته و ذخیره میکنیم. حالا میتونیم تستش کنیم!

اما این کد، هنوز هیچ چیز قابل دسترسی ای نداره. توی main.rb یک کلاس به اسم Page به این شکل مینویسیم، که بشه مدل ما :

class Page
	include Mongoid::Document
	field :title , type: String
	field :text  , type: String
end

خب، حالا میتونیم برای ساختن صفحاتمون اقدام کنیم. ابتدا از طریق شل اینتراکتیو روبی، یک صفحه نمونه میسازیم :

~:$ irb -r ./main.rb

وقتی که شل اینتراکتیو باز شد، این دستورات رو میتونیم توش تایپ کنیم :

hello = Page.new
hello.title = "Hello, World!"
hello.text  = "This is first page on this CMS!"

حالا ما یک صفحه ساختیم. این ساخته شدن میتونه به این شکل هم انجام بشه :

Page.create(title:"My second page", text:"This is second page I added to this CMS!")

بسیار خوب، الان صفحه ها ساخته شده! پس چطوری میتونیم اطلاعاتشون رو نمایش بدیم؟!

برگردیم توی main.rb و این قطعه کد رو اضافه کنیم :

get '/pages' do
	@pages = Page.all
	@title = "Page List"
	erb :index
end

خب، یک پوشه به اسم views باید ایجاد کنیم، یک فایل به اسم index.erb هم درونش قرار میدیم ، و این ها رو در ایندکس مینویسیم :

<h1> Pages </h1>
<% if @pages.any? %>
<p>
<%  @pages.each do |page| %>
<h1><%= page.title %> </h1>
<p> <%= page.text %> </p>
<% end %>
</p>
<% else %>
<h1> No pages added! </h1>
<% end %>

در این کد، یک قالب بندی کلی داریم، همچنین میگیم که اگر پیجی موجود بود، نشونش بده و اگر نبود، پیامی بده و بگو هنوز پیجی اضافه نشده. حالا باید با اجرای برنامه، بتونیم پیج هایی که از طریق کنسول ساختیم رو مشاهده کنیم.

در این قسمت، کلیت یک سیستم مدیریت محتوا رو یاد گرفتیم. فهمیدیم که چطور میشه مدل یک صفحه رو ساخت و بعدش محتواش رو نشون داد. در قسمت بعدی، لینک کردن به پیج های ایجاد شده و همچنین روش ایجاد یک صفحه جدید از طریق خود برناممون رو یاد خواهیم گرفت 🙂

 

در سال ۱۳۹۳ بود که نسخه اول کتاب آموزش روبی نگاشته و منتشر شد، اکنون، در روز ۲۸ شهریور ماه ۱۳۹۵ بعد از گذشت حدود دو سال، دومین نسخه از این کتاب عرضه می شود.

نسخه جدید کتاب علاوه بر این که با فرمت جدیدی نگاشته شده است، به صورت آنلاین (از آدرس : http://book.rubydev.ir ) نیز در دسترس است. همچنین سرفصلهای کتاب تغییر کرده و شکل و شمایل جدیدی به خود گرفته است. سرفصل های کتاب به این شکل هستند :

  • مقدمه
  • آشنایی با روبی
  • پایه ها و مقدمات
  • متغیر ها و انواع داده ها
  • آرایه ها و جداول درهم سازی
  • عملگرها
  • ساختارهای کنترلی
  • حلقه های تکرار
  • توابع
  • برنامه نویسی پیشرفته در روبی
  • برنامه نویسی شی گرا در روبی
  • برنامه نویسی کاربردی در روبی
  • یک پروژه نمونه

rubybookcover

روند کار کتاب جدید، به این شکل است که ابتدا از سیر تا پیاز روبی را به مخاطب آموزش میدهد، سپس یک پروژه با استفاده از چارچوب قدرتمند «سیناترا» اجرا میکند تا کاربر بتواند هرآنچه آموخته است را به کار بگیرد.

لینک دریافت کتاب

 

عبارات با قاعده یا Regular Expression ها چیزهایی هستند که همیشه میتوانند در راحت انجام شدن بسیاری از کارها به ما کمک کنند. برای مثال، فرض کنیم یک اسکریپتی داریم که میخواهد تعداد ایمیل های موجود در لیست کاربران را به ما بگوید. یا این که ببینیم چند درصد از کاربران، از جیمیل، یاهو یا هاتمیل استفاده میکنند. این یکی از استفاده های Regex هاست. به طور کلی، وقتی بدانیم رشته هایی با قواعد خاصی کنار هم چیده می‌شوند، میتوانیم با استفاده از Regex به سادگی الگویی پیاده کنیم که برای ما چک کند آیا ورودی از آن نوع هست یا نه.

الگوی کلی عبارات با قاعده در روبی، به شکل زیر است :

/[0-9a-zA-Z]/ #برای مجموعه ای از کرکترها
/hay/ #برای چک کردن یک قسمت خاص در یک رشته و تطبیق کلی
/\(\)/ #برای چک کردن نمادها

برای چک کردن برابری مقادیر یک رشته با الگوی خاص در روبی از === (سه علامت مساوی) استفاده میکنیم. بعنوان مثال، برنامه زیر به ما میگوید که مقدار وارد شده یک ایمیل است یا خیر :

/[0-9a-zA-Z]\@[0-9a-zA-Z]\.[a-z] === "a@gmail.com"

که این قطعه کد، مقدار true را برمیگرداند. چرا که الگوی کلی یک آدرس ایمیل را داده ایم . برای بهینه تر شدن، میتوانیم یک قطعه کد بنویسیم که چک کند کاربر از چه سرویس دهنده ای استفاده میکند.

if /[0-9a-zA-Z]\@gmail\.com/ === user.email
 puts "User #{user.username} uses Gmail"
end
if /[0-9a-zA-Z]\@yahoo\.com/ === user.email
 puts "User #{user.username} uses Yahoo!"
end

همچنین با استفاده از متد match میتوان چک کرد که آیا بخشی از عبارت ورودی، برابر الگوی وارد شده هست یا نه. برای مثال برنامه بالا را میتوانیم به این شکل بازنویسی کنیم :

if /\@gmail\.com/.match(user.email)
 puts "User #{user.username} uses Gmail"
end
if /\@yahoo\.com/.match(user.email)
 puts "User #{user.username} uses Yahoo!"
end

همچنین، میتوانیم با استفاده از براکت، از تکرار شدن الگوها جلوگیری کنیم. مثلا فرض کنیم قصد داریم ببینیم ورودی ای که کاربر به برنامه داده، یک دستور Lisp است یا خیر، پس به این شکل عمل خواهیم کرد :

/\([\+\-\*\/][0-9][0-9]\)/ === command

و با استفاده از این اساس، میتوان مبادرت به نوشتن Parser های مختلف نمود.

تا اینجا، تا حدودی با ساختار و کاربرد عبارات با قاعده در زبان روبی آشنا شدیم، در مباحث آینده به صورت عملی تر به موضوع خواهیم پرداخت.

 

فرمورک Sinatra یک میکروفرمورک وب است که اکثر کاربران و توسعه دهندگان روبی، با آن آشنایی دارند. برای شروع و ساخت پروژه هایی که زمان زیادی برایشان نداریم، بدون شک این فرمورک یکی از بهترین انتخاب هاست. در اکثر مثالهایی که در اینترنت موجود است، به گفتن متد get بسنده کرده اند. در حالی متد POST هم متد مهمی در فرمورک های وب به شمار می آید. در این آموزش، استفاده از متد post را بررسی میکنیم.

قدم های اولیه

ابتدا یک پوشه به اسم post-app ایجاد کرده، درون این پوشه پوشه دیگری با نام views ایجاد کنید. سپس در همان پوشه post-app فایل app.rb را نیز ایجاد نمایید. در واقع، این ها قدم های اولیه ما برای نوشتن یک برنامه در سیناتراست. درون پوشه views یک فایل با نام form.erb ایجاد کرده، آن را باز کنید و درونش این محتوا را کپی کنید :

<h3>Simple Form</h3>
<form action="/form" method="post">
  <input type="text" name="content">
  <input type="submit">
</form>

سپس به app.rb رفته، آن را باز کرده و این محتوا را درونش قرار دهید :

require 'sinatra'
 
get '/' do
 erb :form
end

اکنون چنانچه برنامه را اجرا کنید، متوجه خواهید شد که هرچه درون فرم بنویسید، طبیعتا باید به یکجا ارسال شود. اما کجا؟ اینجاست که ما متد POST را نیاز داریم.

اضافه کردن post به کد

همانطور که در کد form.erb مشاهده کردید، ما در قسمت action از آدرس form استفاده نمودیم و همچنین نام محتوای داخل فرم را content گذاشتیم. اکنون فایلی به نام content.erb در views ایجاد کرده، آن را باز کنید و محتوای درونش را به این شکل تغییر دهید :

<h2> You Said </h2> 
<h3> <%= params[:content] %> </h3>

سپس به فایل app.rb برگشته و این خطوط را به آن اضافه نمایید :

post '/form' do
 erb :content
end

و اکنون با اجرای برنامه، هرچه درون فرم طراحی شده بنویسید را در آدرس form مشاهده میکنید. با استفاده از متد post میتوانید اطلاعات را درون یک دیتابیس بنویسید و بیشتر استفاده آن نیز در این موارد است.

موفق باشید.

در آموزش پیشین ، در مورد تبدیل نوع کلاس ها و همچنین ارث بری به قدر کافی صحبت شد. در این آموزش، قصد داریم تا در مورد «سر بارگذاری عملگرها» یا Operator Overloading بحث کنیم. وقتی یک کلاس جدید ایجاد میکنیم، به طور مستقیم نمی توانیم روی متغیرهای instance از عملگرها استفاده کنیم. به همین خاطر، مجبوریم که خودمان دوباره اپراتور ها را بازنویسی کنیم.

برای درک بهتر موضوع، وقتی یک عدد مانند ۱ را داخل یک متغیر قرار میدهید، یک شی از کلاس Fixnum ایجاد شده و این شی قابلیت این را دارد که با شی دیگری از کلاس Fixnum جمع بسته شود، از آن کم شود و … . بنابراین، نیاز به این داریم که تعریف کنیم عملگری مانند + وجود دارد که با استفاده از آن، میتوان عدد دیگری اضافه نمود. بیایید یک کلاس به نام TestNumber ایجاد کنیم و عملگر + را برایش تعریف کنیم.

class TestNumber
 def initialize(x)
  @x = x
 end
 def +(y)
  @x + y
 end
end

اگر دو شی از این کلاس ایجاد کنید و بخواهید روی آنها عملیات انجام دهید، حتما به مشکل میخورید. چرا که ما تعریف کردیم که متغیر x با y جمع شود و نه yی که در یک کلاس دیگر تعریف شده است.

برای این که x ما با yی که در یک کلاس دیگر تعریف شده است جمع بسته شود نیاز داریم تا متغیرهای instance آن کلاس را هم فراخوانی کنیم. پس کد ما به این شکل تغییر خواهد کرد :

class TestNumber
 attr_accessor :x
 def initialize(x)
  @x = x
 end
 def +(other)
  y = other.x
  TestNumber.new(@x + y)
 end
end

با استفاده از attr_accessor میتوانیم به متغیرهای instance دیگر کلاس ها دسترسی مستقیم داشته باشیم و مانند یک متد آنها را فراخوانی کنیم.

در این آموزش، مبحث Operator Overloading را پوشش دادیم. در آموزش های بعدی، به سایر مفاهیم و تکنیک های برنامه نویسی شی گرا در روبی خواهیم پرداخت.