Очень часто мы хотим, чтобы наши модели находились не просто в папке 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
.
Счастливого кодинга!