Модульные модели в Ruby on Rails

Очень часто мы хотим, чтобы наши модели находились не просто в папке model, а в папке module, что имеет множество преимуществ.
Одно из преимуществ – возможно, имена таблиц уже есть в проекте, поэтому, добавив префикс к имени модуля, можно сделать таблицу уникальной.
Следующее преимущество – если вы хотите разместить функциональность отдельно от остальной части проекта, мы можем использовать модульные модели.
Последнее преимущество – создание движков для использования в других проектах, включая таблицы, может быть легко осуществлено с помощью префикса таблиц.

Как это сделать? Очень просто!

Предположим, мы хотим, чтобы в нашем проекте был блог, который является отдельной функциональностью по сравнению с остальной частью проекта. Итак, мы создадим две модели, Post и Comment.

Поэтому запустите проект:

rails g model blog/post title:string body:text 
Войти в полноэкранный режим Выйти из полноэкранного режима

Это создаст модель со следующими файлами:
blog.rb

# app/models/blog.rb

module Blog
  def self.table_name_prefix
    'blog_'
  end
end
Войти в полноэкранный режим Выйти из полноэкранного режима

blog/post.rb

# app/models/blog/post.rb

module Blog
  class Post < ApplicationRecord
    validates :title, presence: true
    validates :body, presence: true
  end
end
Войти в полноэкранный режим Выйти из полноэкранного режима

И файл миграции создаст таблицу с именем blog_posts, а не просто posts.

Теперь, создание комментариев в посте несколько сложнее.
Выполните в терминале следующее:

rails g model blog/comment body:text blog_post:references user:references
Войти в полноэкранный режим Выйти из полноэкранного режима

Это попросит переопределить blog.rb, который в данный момент не нужен.
Новый файл модели комментариев должен быть обновлен:

# app/models/blog/comment.rb

module Blog
  class Comment < ApplicationRecord
    validates :body, presence: true
    belongs_to :blog_post, class_name: 'Blog::Post'
  end
end
Войти в полноэкранный режим Выйти из полноэкранного режима

И обновите модель поста с отношением:

# app/models/blog/post.rb

has_many :comments, class_name: 'Blog::Comment', dependent: :destroy, foreign_key: :blog_post_id, inverse_of: :blog_post
Войти в полноэкранный режим Выйти из полноэкранного режима

Окончательные выводы

Итак, теперь у нас есть модульные модели в проекте. Созданные таблицы будут blog_posts и blog_comments. В любом месте проекта для вызова модели постов нужно использовать Blog::Post, например Blog::Post.find 12. Но мы можем использовать .comments, например:

# rails console
post = Blog::Post.find 1
post.comments.last
# similar for comments
comment = Blog::Comment.last
comment.post.title
Войти в полноэкранный режим Выйти из полноэкранного режима

Однако в базе данных у нас будет таблица blog_posts и таблица blog_comments с внешним ключом blog_post_id.


Счастливого кодинга!

Оцените статью
Procodings.ru
Добавить комментарий