Every so often we want our models not just in model folder but in module in a folder with many advantages inclusive.
One advantage is maybe those table names are already in project, so by putting a prefix of module name can make the table uniqueness.
Next advantage is you want to put the functionality separate with the rest of the project, we can use modular models.
Last advantage is making engines to be used in other projects, including tables, can be easy using prefixed tables.
How to do it? It’s easy!
Let’s assume we want a blog to our project, which is a separate functionality than the rest of the project. So, we will be creating two models, Post and Comment.
Therefore, run in the project:
rails g model blog/post title:string body:text
This will create a model with the following files:
# app/models/blog.rb module Blog def self.table_name_prefix 'blog_' end end
# app/models/blog/post.rb module Blog class Post < ApplicationRecord validates :title, presence: true validates :body, presence: true end end
And the migration file will create the table named
blog_posts not just simple
Now, creating the comments in the post is somewhat tricky.
Run the following in the terminal:
rails g model blog/comment body:text blog_post:references user:references
This will ask to override the
blog.rb which is not needed at the moment.
The new file of comment model needs to be updated:
# app/models/blog/comment.rb module Blog class Comment < ApplicationRecord validates :body, presence: true belongs_to :blog_post, class_name: 'Blog::Post' end end
And update the post model with relation:
# app/models/blog/post.rb has_many :comments, class_name: 'Blog::Comment', dependent: :destroy, foreign_key: :blog_post_id, inverse_of: :blog_post
So now we have modular models in the project. Tables created will be
blog_comments. Anywhere in project to call post model you have to use
Blog::Post.find 12. But we can use
# rails console post = Blog::Post.find 1 post.comments.last # similar for comments comment = Blog::Comment.last comment.post.title
However, in database we will have
blog_posts table and
blog_comments table with foreign key