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

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

  • ایجاد مدل پست
  • ارتباط بین کاربر و مدل‌های پست
  • استفاده از Active Storage برای الصاق یک تصویر به هر پست
  • ایجاد یک پست جدید و افزودن اعتبارسنجی پست
  • نمایش پست‌ها روی صفحه اصلی و صفحه پروفایل کاربران
  • استفاده از Kaminari gem برای صفحه‌بندی پست‌ها
  • آپلود آواتار برای کاربر

ایجاد مدل پست

مدل‌ها در Rails از یک اسم مفرد و جداول متناظر آن‌ها در پایگاه داده از یک اسم جمع استفاده می‌کنند. برای ایجاد مدل Post باید از generator در Rails استفاده کنیم و دستور زیر را در ترمینال وارد نماییم:

دستور فوق دسته‌ای از فایل‌ها را ایجاد می‌کند:

اکنون باید 2 فایل به نام‌های app/models/post.rb و db/migrate/20180922091640_create_posts.rb را در نظر بگیریم.

ابتدا فایل db/migrate/20180922091640_create_posts.rb را در ویرایشگر متنی باز کنید:

این فایل یک migration است که جدول Posts را با 2 ستون به نام های description (نوع string) و user_id (نوع integer) ایجاد می‌کند.

Migration فوق را اجرا می‌کنیم تا جدول Posts ایجاد شود:

و نتیجه به صورت زیر است:

برای مطالعه موارد بیشتر در مورد migration می‌توانید به این آدرس (+) مراجعه کنید.

مدل Post را در فایل app/models/post.rb باز کنید:

این همان مدل پست است که به جدول Posts در پایگاه داده ما نگاشت شده است.

افزودن ارتباط بین مدل‌های کاربر (User) و پست (Post)

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

ویژگی پشتیبانی Active Record موجب شده است که اعلان ارتباط‌ها ساده‌تر صورت بگیرد. بدون وجود ارتباط وضعیت به صورت زیر است:

اما پس از اعلان یک ارتباط به صورت زیر در می‌آید:

ارتباط has_many نشان دهنده یک اتصال «یک به چند» با مدل دیگر است. و گزینه dependent::destroy نشان دهنده این است که همه پست‌های مرتبط زمانی که کاربر حذف شود باید از بین بروند.

معرفی Active Storage

Active Storage یکی از ویژگی‌های عالی نسخه 5.2 Rails است. این ویژگی برای آپلود فایل‌ها به یک سرویس ذخیره‌سازی ابری مانند Amazon S3، Google Cloud Storage یا Microsoft Azure Storage معرفی شده است و این فایل‌ها را به شی‌ءهای Active Storage الصاق می‌کند.

Active Storage به وسیله یک سرویس local disk-based برای توسعه و تست کردن ارائه شده است. برای راه‌اندازی Active Storage باید دستور زیر را اجرا کنیم:

یک فایل migration مانند db/migrate/20180924134051_create_active_storage_tables.active_storage.rb ایجاد می‌کنیم و سپس دستور rails db:migrate را برای انجام مهاجرت اجرا می‌کنیم:

این migration 2 جدول به نام‌های active_storage_blobs و active_storage_attachments ایجاد می‌کند که Active Storage از آن‌ها برای ذخیره‌سازی فایل‌ها استفاده می‌کند.

پیکربندی سرویس‌هایی برای ذخیره‌سازی فایل‌ها

Active Storage سرویس‌هایی در config/storage.yml اعلان می‌کند. این فایل را باز کنید تا پیکربندی پیش‌فرض را به صورت زیر مشاهده کنید:

این پیکربندی بدان معنی است که اپلیکیشن ما دو سرویس به نام های test و local دارد. هر دو این سرویس‌ها از سرویس Disk استفاده می‌کنند. شما می‌توانید از سرویس‌های دیگری نیز استفاده کنید. برای مثال می‌توانیم سرویس جدیدی با نام amazon به صورت زیر به فایل config/storage.yml اضافه کنیم:

در اغلب موارد هر محیط از یک سرویس متفاوت استفاده می‌کند. در محیط توسعه می‌توانیم از سرویس Disk با افزودن کد پیکربندی به config/environments/development.rb استفاده کنیم:

برای استفاده از سرویس Amazon S3 در محیط production می‌توانید کد زیر را به فایل config/environments/production.rb اضافه کنید:

هنگام به‌روزرسانی پیکربندی در هر محیط باید سرور را ری‌استارت کنید.

استفاده از Active Storage برای ذخیره‌سازی تصاویر پست‌ها

در این بخش به بررسی عملی روش استفاده از Active Storage برای ذخیره‌سازی تصاویر مربوط به هر پست می‌پردازیم.

الصاق تصویر به پست

ما از ماکروی has_one_attached برای راه‌اندازی رابطه یک به یک بین Post و Image استفاده می‌کنیم. هر پست می‌تواند یک تصویر الصاق شده داشته باشد.

ایجاد یک پست جدید

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

گردش کار ایجاد یک Post جدید به صورت زیر است:

  • ایجاد یک کنترلر Post
  • افزودن اکشن Create به کنترلر پست
  • افزودن یک Form برای ایجاد Post

ایجاد کنترلر Post

افزودن اکشن create

ما قصد داریم یک اکشن Create به کنترلر Post اضافه کنیم:

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

افزودن یک فرم برای ایجاد Post جدید به صفحه اصلی

کد HTML فرم ما به صورت زیر خواهد بود:

ما از متد کمکی file_field برای آپلود تصویر استفاده می‌کنیم.

user_id آن کاربری که پست را ایجاد می‌کند یعنی current_user است و این فیلد را در فرم با استفاده از کلاس CSS به نام d-name پنهان می‌کنیم:

مسیر اکشن‌های new و create را به Post اضافه می‌کنیم:

کد CSS به صورت زیر است:

فرم ایجاد یک پست جدید
فرم ایجاد یک پست جدید

افزودن اعتبارسنجی به Post

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

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

از آنجا که Active Storage هنوز از اعتبارسنجی الصاق فایل‌ها پشتیبانی نمی‌کند، باید از یک متد سفارشی برای تأیید وجود تصویر در پست‌ها استفاده کنیم.

افزودن اعتبارسنجی به مدل Post

ما از image_presence برای اعتبارسنجی پست استفاده می‌کنیم. این متد هنگام افزودن پستی بدون تصویر یک خطا با پیام can’t be blank نمایش می‌دهد و زمانی که پست نامعتبر باشد، پست نمی‌تواند ایجاد شود.

متدهای اعتبارسنجی چه زمانی اجرا می‌شوند؟

Rails پیش از ذخیره‌سازی شیء Active Record، اعتبارسنجی ما را اجرا می‌کند. اگر اعتبارسنجی هر گونه خطایی تولید کند، Rails شیء را ذخیره نخواهد کرد. این وضعیت را می‌توانید در کنسول مرورگر امتحان کنید:

اینک پست‌های ما با وجود اعتبارسنجی در شیء Post همیشه شامل تصویر خواهند بود.

نمایش پست‌ها در صفحه اصلی

پس از افزودن موفق پست‌های جدید، در این مرحله قصد داریم آن‌ها را در صفحه اصلی نمایش دهیم. ما همه پست‌ها را بر اساس ترتیب فیلد created_at نمایش می‌دهیم.

در HomeController متغیر posts را اضافه می‌کنیم که شامل همه پست‌های مرتب شده در اکشن index است.

در ویوی app/views/home/index.html.erb پست‌ها را به صورت زیر نمایش می‌دهیم:

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

کد HTML این بخش به صورت زیر است:

استایل CSS نیز به صورت زیر است:

اینک پست‌های ما به صورت زیر در آمده‌اند:

یک پست در صفحه اصلی
یک پست در صفحه اصلی

نمایش پست‌ها روی صفحه پروفایل کاربر

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

از آنجا که User و Post ارتباط‌هایی به صورت has_many دارند، این بدان معنی است که یک کاربر می‌تواند چندین پست داشته باشد و از این رو می‌توانیم به سهولت پست‌های کاربر را با استفاده از current_user.posts بازیابی کنیم.

در بخش show در UsersController یک متغیر وهله posts در صفحه اصلی اضافه می‌کنیم. این همان posts است که در آن کاربر جاری بر اساس فیلد created_at مرتب‌سازی شده‌اند.

کد HTML را در بخش user-images به‌روزرسانی می‌کنیم:

تعداد پست‌های کاربر جاری را نیز به‌روزرسانی می‌کنیم:

افزودن صفحه‌بندی برای پست‌ها

اضافه کردن امکان صفحه‌بندی در Rails با استفاده از kaminari gem کاملاً ساده است. kaminari یک ابزار صفحه‌بندی مبتنی بر Scope و Engine به صورت تمیز، قدرتمند، قابل سفارشی‌سازی و با امکانات مختلف برای فریمورک‌های وب اپلیکیشن مدرن و ORM ها محسوب می‌شود.

استفاده از kaminari gem کاملاً آسان است، کافی است gem را در اپلیکیشن وارد کنید تا مدل‌ها آماده استفاده باشند. در واقع هیچ پیکربندی مورد نیاز نیست. لزومی به تعریف کردن هیچ چیزی در مدل‌ها یا helper-ها نیست.

نصب

برای نصب در اپلیکیشن خط زیر را در Gemfile خود بنویسید:

سپس bundle را اجرا کنید:

روش استفاده از صفحه‌بندی برای پست‌ها

کد موجود در کنترلر Home به صورت زیر است:

  • حیطه (scope) برای page: به تعریف چندمین صفحه‌ای از پست‌ها که باید واکشی شوند می‌پردازد.

مثال: (Post.page(3 به این معنی است که باید سومین صفحه از پست‌ها واکشی شود.

دقت کنید که صفحه‌بندی از صفحه 1 آغاز می‌شود و نه از صفحه صفر، چون, (page(0 همان نتیجه مشابه (page(1 را بازگشت می‌دهد.

  • حیطه (scope) برای per: برای نمایش تعداد پست‌هایی که باید در هر صفحه قرار گیرند استفاده می‌شود و مقدار پیش‌فرض آن 25 است.

مثال (Post.page(3).per(5 به این معنی است که تعداد پست‌ها باید 5 باشد.

در View یک helper برای paginate ایجاد کنید:

این کد چند لینک صفحه‌بندی?page=N که با تگ <nav> اچ‌تی‌ام‌ال پیچیده شده‌اند رندر می‌کند. بدین ترتیب چندین لینک صفحه‌بندی مانند زیر در خروجی ارائه می‌شود:

متد helper به نام paginate را به ویوی با نام home/index.html.erb اضافه کنید:

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

به سمت انتهای صفحه اسکرول کنید تا لینک‌های صفحه‌بندی را ببینید:

لینک‌های صفحه‌بندی
لینک‌های صفحه‌بندی

شما می‌توانید لینک‌های صفحه‌بندی 1 2 3 4 Next ›Last » را ببینید. UI این اپلیکیشن چندان زیبا نیست و به همین دلیل CSS زیر را برای بهتر شدن ظاهر آن اضافه می‌کنیم:

افزودن یک آواتار برای کاربر

ما می‌توانیم از Active Storage جهت افزودن آواتار برای کاربران استفاده کنیم.

در Model

در مدل از آنجا که هر کاربر یک آواتار دارد، بنابراین مدل User را به صورت زیر تعریف می‌کنیم:

در View (فرم ویرایش کاربر)

در Controller

افزودن آواتار به strong params

اکنون می‌توانیم به صفحه Edit user برویم و یک آواتار برای کاربر آپلود کنیم.

نمایش آواتار برای کاربر

  • در صفحه پروفایل کاربر (users/show.html.erb):
  • در صفحه فرم ویرایش پروفایل کاربر (users/edit.html.erb):
  • در صفحه اصلی (home/index.html.erb):

آواتار کاربران هر پست به صورت زیر است:

برای تعیین این که کاربر آواتار دارد یا نه می‌توانید متد ?user.avatar.attached را فراخوانی کنید.

با کلیک روی آواتار کاربران می‌توانید پروفیل کاربران دیگر را مشاهده کنید. اکشن show را در UsersController به‌روزرسانی کنید. current_user را با کاربری که با به وسیله id کوئری کرده‌اید تعویض کنید:

  • در صفحه اصلی (home/index.html.erb):

لینک‌ها برای آواتار و نام کاربری آن کاربر که به صفحه کاربری‌اش می‌روید اضافه کنید.

اکنون در صفحه اصلی می‌توانیم روی آواتار یا نام کاربری آن کاربری که می‌خواهیم جزییات پروفایلش را مشاهده کنیم کلیک کنیم.

سخن پایانی

در این مقاله به معرفی جزییاتی در مورد مدل (Active Record) آموختیم. این موارد شامل ایجاد یک مدل جدید، اعتبارسنجی، و ایجاد ارتباط بوده است. همچنین در مورد ویژگی Active Storage و چگونگی استفاده از آن برای آپلود تصاویر آموختیم. در نهایت شیوه استفاده از Kaminari gem برای صفحه‌بندی را مشاهده کردیم.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

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

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *