[Ruby on Rails] Since I finished all Rails Tutorial, I tried to implement an additional "stock function"

Introduction

I implemented a function to stock articles like "qiita" in Rails, so I will summarize the method as a memorandum. (Basically the same way as the like function)

To implement

-Create a button to stock articles. -Display how much articles are in stock. -Allow stocked posts to be checked on the stock list page.

Create a Stock model

The first step in implementing the stock feature is to create a Stock model.

$ rails g model Stock

Create two columns. -Post_id column -User_id column Modify the migration file as follows.

xxxxxxxxxxxxx_create_stocks.rb


class CreateStocks < ActiveRecord::Migration[6.0]
  def change
    create_table :stocks do |t|
      t.references :user, foreign_key: true
      t.references :post, foreign_key: true

      t.timestamps
    end
    add_index :stocks, [:user_id, :post_id], unique: true
  end
end
$ rails db:migrate

Add each of the two columns as a foreign key. This table will be used as an intermediate table to store information such as ** who stocked which post **. Also, set the index so that the combination of the user_id column and the post_id column is unique.

Set up an association

Set up the association as follows: Add validation to stock.rb in addition to the association.

user.rb

user.rb


has_many :stocks, dependent: :destroy

post.rb

post.rb


has_many :stocks, dependent: :destroy

stock.rb

stock.rb


belongs_to :user
belongs_to :post

validates :user_id, presence: true
validates :post_id, presence: true

Create a stock controller

Then create a stock controller.

$ rails g controller Stocks

Add processing to the controller

stocks_controller.rb After creating the stock controller, define the actions required for this implementation.

stocks_controller.rb


class StocksController < ApplicationController

  def create
    @stock = current_user.stocks.create(post_id: params[:post_id])
    redirect_back(fallback_location: root_path)
  end
  
  def destroy
    @stock = Stock.find_by(
      post_id: params[:post_id],
      user_id: current_user.id
      )
    @stock.destroy
    redirect_back(fallback_location: root_path)
  end

  def index
    @stocks = Stock.where(user_id: current_user.id)
  end
end

posts_controller.rb Then add a variable to the ** show action ** part of the post controller. This is to display the stock button on the post/show page.

posts_controller.rb


  def show
    @post = Post.find_by(id: params[:id])
    @stock = Stock.find_by(
      user_id: current_user.id,
      post_id: @post.id
    )
  end

Set up routing

Next, we will add the necessary routing. routes.rb

routes.rb


resources :stocks, only:[:create, :destroy, :index]

This time, in addition to the stocking function ** (create) ** and the stocking release function ** (destroy) **, ** "index" ** for displaying stocked articles is also added.

Add to the process of confirming whether it is in stock

Define a stock? Method so that the user can check if the article is already in stock. user.rb

user.rb


  #Check if the user is already in stock
  def stock?(post)
    self.stocks.exists?(post_id: post.id)
  end

Add & change View

In order to implement the stock button, we will first create three partials. shared/_stock.html.erb

ruby:_stock.html.erb


<%= form_with(url:stocks_path, local: true) do |f| %>
  <div><%= hidden_field_tag :post_id, @post.id %></div>
 <%= f.submit "stock", class:"btn-sm" %>
<% end %>

shared/_unstock.html.erb

ruby:_unstock.html.erb


<%= form_with(url: stock_path(@stock), html: {method: :delete}, local: true) do |f| %>
  <div><%= hidden_field_tag :post_id, @post.id %></div>
  <%= f.submit "Stop stocking", class:"btn-sm" %>
<% end %>

shared/_stock_form.html.erb

ruby:_stock_form.html.erb


<% if current_user.stock?(@post) %>
  <%= render "shared/unstock" %>
<% else %>
  <%= render "shared/stock" %>
<% end %>
<%= @post.stocks.count %>

posts/show Add the following partial where you want to add the button.

ruby:show.html.erb


<%= render "shared/stock_form" %>

stocks/index.html.erb Add a new indek page to display stocked articles.

ruby:index.html.erb


<h1>Stock list</h1>
<h2>A list of portfolios you have stocked.</h2>

<% @stocks.each do |stock| %>
  <%= link_to stock.post.name, post_path(stock.post) %>
<% end %>

Completed picture

end

That is all. I don't care about the design at all because it describes how to implement the function. Please add the design as you like.

Click here for source code

I'm working on a portfolio. It is below. https://github.com/iittaa/Sharing_Portfolio

Recommended Posts

[Ruby on Rails] Since I finished all Rails Tutorial, I tried to implement an additional "stock function"
Rails Tutorial Extension: I tried to create an RSS feed function
[Rails] I tried to implement "Like function" using rails and js
I tried to implement Ajax processing of like function in Rails
I want to add a browsing function with ruby on rails
I tried to implement the image preview function with Rails / jQuery
[Ruby on Rails] Rails tutorial Chapter 14 Summary of how to implement the status feed
How to implement image posting function using Active Storage in Ruby on Rails
Rails6 I tried to introduce Docker to an existing application
[Ruby on Rails] How to implement tagging / incremental search function for posts (without gem)
I tried installing Ruby on Rails related plugin with vim-plug
I tried to implement the like function by asynchronous communication
I tried to make a reply function of Rails Tutorial extension (Part 3): Corrected a misunderstanding of specifications
[Swift] I tried to implement the function of the vending machine
[Ruby on Rails] Implement login function by add_token_to_users with API
I tried to make a message function of Rails Tutorial extension (Part 2): Create a screen to display
Since I switched from Spring Boot (Java) to Ruby on Rails, I summarized my favorite points of Rails.
Things to remember and concepts in the Ruby on Rails tutorial
(Ruby on Rails6) Create a function to edit the posted content
I tried to make a group function (bulletin board) with Rails
[Ruby on Rails] Introduced paging function
How to use Ruby on Rails
[Ruby on Rails] CSV output function
[Ruby on Rails] Comment function implementation
[Ruby on Rails] DM, chat function
I don't know anything, I tried to make TODO while studying ruby ​​on rails for 3 days by myself
Rails API mode I tried to implement the keyword multiple search function using arrays and iterative processing.
[Rails] I tried to implement a transaction that combines multiple DB processes
How to implement gem "summer note" in wysiwyg editor in Ruby on Rails
[Ruby on Rails] Search function (not selected)
[Rails] Addition of Ruby On Rails comment function
[Ruby on Rails] Creating an inquiry form
I tried to introduce CircleCI 2.0 to Rails app
[Ruby on Rails] Follow function implementation: Bidirectional
Deploy to Heroku [Ruby on Rails] Beginner
I tried to implement the Iterator pattern
Preparing to introduce jQuery to Ruby on Rails
[Ruby on Rails] How to use redirect_to
[Ruby on Rails] How to use kaminari
I tried to build Ruby 3.0.0 from source
[Ruby on rails] Implementation of like function
[Ruby on Rails] Button to return to top
I tried to implement ModanShogi with Kinx
[Ruby on Rails] Logical deletion (withdrawal function)
I tried to implement a function equivalent to Felica Lite with HCE-F of Android
[Rails / JavaScript / Ajax] I tried to create a like function in two ways.
Validation settings for Ruby on Rails login function
Deploy to Ruby on Rails Elastic beanstalk (EB deploy)
I tried to implement polymorphic related in Nogizaka.
[Rails] I tried to raise the Rails version from 5.0 to 5.2
[Ruby basics] I tried to learn modules (Chapter 1)
Ruby on Rails Email automatic sending function implementation
[Ruby on Rails] Let's build an environment on mac
I tried installing docker on an EC2 instance
I tried to develop an application in 2 languages
[Ruby on Rails] How to install Bootstrap in Rails
[Ruby on Rails] How to use session method
I tried to implement a server using Netty
[Ruby on Rails] Post editing function (update, delete)
I made a portfolio with Ruby On Rails
[Rails] How to connect to an external API using HTTP Client (I tried connecting to Qiita API)