As the title suggests, we will create a simplified Instagram app. I will write the article in the following steps, so I hope you will read it step by step.
① App creation-Implementation of login function ② Implementation of photo posting function ← Imakoko ③ [Implementation of user page] (https://qiita.com/maca12vel/items/c716702b02f977303011) ④ [Implementation of follow function] (https://qiita.com/maca12vel/items/2760d33f3683fac91de5) ⑤ Implementation of post deletion function
What is Active Storage ... A function for uploading files If you use this, you can easily create an image posting function etc. with a form.
Terminal
rails active_storage:install
Next, create a photo model.
Since  photo is associated with  user, ```user: belongs_to Create a text type column by setting caption: text``
Terminal
rails g model photo user:belongs_to caption:text
And
Terminal
rails db:migrate
Finally, create the controller.
Terminal
rails g controller photos
The preparation is complete.
First, set the routing.
routes.rb
Rails.application.routes.draw do
  root 'homes#index'
  devise_for :users
  resources :photos #← here
end
Next, edit the home screen.
erb:app/views/homes/index.html.erb
<h3>home</h3>
<div>
  <%= link_to 'logout', destroy_user_session_path, method: :delete %>
</div>
<div>
  <%= link_to 'Photo posting', new_photo_path %>
</div>
Check  new_photo_path with Prefix of ** rails routes **

Create  new.html.erb in the photos model and write as follows for confirmation.
erb:app/views/photos/new.html.erb
<h3>Photo posting</h3>
If you can move from the home screen to the photo posting page as shown below, you are successful.

I will describe it in the controller created by  rails g controller photos.
photos_controller.rb
class PhotosController < ApplicationController
  before_action :authenticate_user!
  def new
    @photo = current_user.photos.new
  end
  def create
    @photo = current_user.photos.new(photo_params)
    if @photo.save
      redirect_to :root
    else
      render :new
    end
  end
  private
  def photo_params
    params.require(:photo).permit(:caption, :image)
  end
end
With before_action: authenticate_user!,
It is set so that only logged-in users can post.
 Create action with argument (photo_params)
(photo_params) is defined under  private.
Also with the create action
If the save is successful, the home screen will be displayed.
** If it fails, it is set to return (stay) to the new posting screen **.
Before that, check the association between the ʻuser model and the "photos model`.
Since user and photos have a one-to-many relationship, edit as follows.
user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_many :photos #← here
end
photo.rb
class Photo < ApplicationRecord
  belongs_to :user #← Described at rails g model photo
  has_one_attached :image #← here
end
 has_one_attached: Column name is used to attach one image to the model.
When linking multiple images, use  has_many_attached: column name.
Since this is one image, it is called  has_one_attached.
By the way, the way of writing when displaying an image is different between one and many.
has_one_attached
<%= image_tag(@photo.image) %>
has_many_attached
<% images.count.times do |i| %>
  <%= image_tag(@photo.image[i]) %>
<% end %>
 has_many_attached: column name
The image is stored as an array, so it looks like the above.
Although the introduction has become long, I will edit the view of the new post screen.
erb:app/views/photos/new.html.erb
<h3>Photo posting</h3>
<%= form_with model: @photo, local: true do |f| %>
  <div>
    <%= f.file_field :image %>
  </div>
  <div>
    <%= f.text_area :caption %>
  </div>
  <%= f.submit %>
<% end %>
Display the posted image on the home screen.
erb:app/views/homes/index.html.erb
<h3>home</h3>
<div>
  <%= link_to 'logout', destroy_user_session_path, method: :delete %>
</div>
<div>
  <%= link_to 'Photo posting', new_photo_path %>
</div>
<% current_user.photos.each do |photo| %>
  <div>
    <p><%= photo.caption %></p>
    <%= image_tag photo.image %>
  </div>
I try to display all posts in each statement.
From the new post page, click  Select File,  Enter caption,  Create Photo,
If you can post as follows, I think that it is in shape for the time being.

that's all. Thank you for your hard work.
Next → ③ [Implementation of user page] (https://qiita.com/maca12vel/items/c716702b02f977303011)
Recommended Posts