
Models (Practice) | Ruby on Rails
Practical task for the topic in the Model
Create the Author(name) and Post(title, description, author_id) models. Create a PostsController with two actions: index and show. Also create paths and corresponding views for these actions. The index page displays all posts, and the show page displays a single selected post. Create an AuthorsController with the index and show actions. On the index page of this controller, display all authors, and on the show page, display information about a specific author and his posts. Provide the ability to go to the author's page from the post page.
Let's create an authors table in the database.
rails generate model Author name:string
class CreateAuthors < ActiveRecord::Migration[7.1]
def change
create_table :authors do |t|
t.string :name
t.timestamps
end
end
end
Create a posts table in the database.
rails generate model Post title:string description:text author:references{foreign_key:true}
class CreatePosts < ActiveRecord::Migration[7.1]
def change
create_table :posts do |t|
t.string :title
t.text :description
t.references :author, foreign_key: true
t.timestamps
end
end
end
Now let's establish a "one-to-many" relationship between our models.
class Post < ApplicationRecord
belongs_to :author
end
class Author < ApplicationRecord
has_many :posts
end
Create a PostsController with actions: index and show.
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
end
end
In the index action, display all posts from the database. In the show action, retrieve a specific post by id.
Create routes for these actions.
Rails.application.routes.draw do
root "posts#index"
resources :posts, only: %i[index show]
end
Create corresponding views for index and show actions. Display a list of posts on the index page.
# app/views/posts/index.html.slim
h1 Posts
= render partial: 'post', collection: @posts
# app/views/posts/_post.html.slim
.post
h1 = post.title
p = post.description
h5 = post.author.name
= link_to 'View', post_path(post.id)
In the show view, we can access an individual post.
# app/views/posts/show.html.slim
h1 = @post.title
p = @post.description
= link_to 'All Posts', posts_path
Create an AuthorsController with actions: index and show.
class AuthorsController < ApplicationController
def index
@authors = Author.all
end
def show
@author = Author.find(params[:id])
@posts = @author.posts
end
end
In the index action, display all authors from the database. In the show action, retrieve a specific author by id and fetch their posts.
Create routes for these actions.
resources :authors, only: %i[index show]
Create corresponding views for index and show actions. Display a list of authors on the index page.
# app/views/authors/index.html.slim
h1 Authors
= render partial: 'author', collection: authors
= link_to 'All Posts', posts_path
# app/views/authors/_author.html.slim
.author
h1 = author.name
= link_to 'View', author_path(author.id)
In the show view, we can access an individual author.
# app/views/authors/show.html.slim
h1 = @author.name
- if @posts
h3 List of author's posts
= render partial: 'posts/post', collection: @posts
= link_to 'Go Back', authors_path
Let's also provide the ability to navigate to the authors index page from the posts index page.
# app/views/posts/index.html.slim
...
= link_to 'All Authors', authors_path
Enable the ability to navigate to an author's page from a post page.
# app/views/posts/show.html.slim
h1 = @post.title
p = @post.description
span Author:
= link_to @post.author.name, author_path(@post.author_id)
br
= link_to 'All Posts', posts_path
This is one solution to our task. If you have alternative approaches to certain aspects of our task, feel free to mention them in the comments.