LoginSignup
0
0

More than 3 years have passed since last update.

class_nameオプションを使ったミニアプリ

Last updated at Posted at 2020-08-19

はじめに

・前回の記事はこちら↓
商品を売ったり買ったりする場合にclass_nameを使ってみた
https://qiita.com/fishmans0120/items/5b40fb2a057e4d722a67
・備忘録として書いています。
・間違いなどあればご指摘いただけますと幸いです。

今回の前提条件とゴールについて

・usersテーブルがある
・itemsテーブルがある
・商品を売ったり買ったりすると仮定する
・中間テーブルはつくらない
・seller_idにログインユーザーのidが表示される←ここをゴールにします

さっそくミニアプリを作ってみます

ターミナル
$ rails _6.0.0_ new class_name_app -d mysql

railsのバージョンを6.0.0に指定して、
class_name_appという名前のアプリケーションを、
データベースMySQLで、
生成します。

ターミナル
$ cd class_name_app/

ディレクトリを移動しました。
ユーザーを生成するためと、haml記法を使うためにgemをインストールします。

Gemfile
gem `devise`
gem `haml-rails`
ターミナル
$ bundle install

これでdeviseとhaml-railsが使えるようになりました。
データの保存形式を変更します。

config/database.yml
# encoding: utf8mb4
encoding: utf8

データベースを生成しましょう。

ターミナル
$ rails db:create

ではitemsテーブルを作っていきます。

ターミナル
$ rails g model item
db/migrate/20200818025529_create_items.rb
class CreateItems < ActiveRecord::Migration[6.0]
  def change
    create_table :items do |t|
      # 商品名を入力するためにstring型でnameカラムを作成します
      t.string :name

      t.timestamps
    end
  end
end
ターミナル
$ rails db:migrate

これでitemsテーブルができました。
nameカラムがstring型で追加されています。

次にusersテーブルを作ります。

ターミナル
$ rails g devise:install
$ rails g devise user
$ rails db:migrate
$ rails haml:erb2haml

この順で入力してください。
usersテーブルができあがります。
サインアップ、ログイン、ログアウトもできるようになりました。
最後のコマンドは現在erb記法で記述されているファイルをhaml記法に変換するコマンドです。途中で入力を求められたらyを入力してください。

なお、今回はusersテーブルにユーザー名を表示させるnameカラムを作っていません。
必要であれば追加してください。

itemsコントローラーを生成して、ルーティングも設定します。

app/controllers/items_controller.rb
class ItemsController < ApplicationController
  def new
    @item = Item.new
  end
  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to new_item_path
    else
      render 'new'
    end
  end

  private
  def item_params
    params.require(:item).permit(:name).merge(seller_id: current_user.id)
  end
end
confin/routes.rb
Rails.application.routes.draw do
  devise_for :users
  resources :items
  root 'items#new'
end

ビューファイルはこのようにします。

app/views/new.html.haml
%h1 Items#new
%p Find me in app/views/items/new.html.haml

.logout
  = link_to "ログアウト", destroy_user_session_path, method: :delete
.login
  = link_to "ログイン", new_user_session_path, class: "post"
.signup
  = link_to "新規登録", new_user_registration_path, class: "post"
.form
  = form_with model: @item, local: true do |f|
    = f.text_field :name
    = f.submit "送信"

ざっくり言うと、
・newアクションで新規入力し、createアクションでデータを新規登録する
・ちゃんとセーブできたらnew画面へリダイレクト、セーブできなかったらnew画面へデータそのままで戻る
・localhost:3000へアクセスしたら自動的にnew画面になりますよ
・ログアウトボタンを押すとログインしてない状態になります
・ログインボタンを押すとログイン画面に遷移します
・新規登録ボタンを押すとサインアップ画面に遷移します
・商品名を入力して送信ボタンを押すとテーブルにデータが保存されます

こんな感じです。でもまだやることが残っています。
モデルファイルに追記しましょう。

models/item.rb
class Item < ApplicationRecord
  belongs_to :buyer, class_name: "User", foreign_key: "buyer_id", optional: true
  belongs_to :seller, class_name: "User", foreign_key: "seller_id"
end

ここ大事!!!

Rails 5.1からの変更点として、belongs_toを指定した時、自動的にrequired: trueオプションが追加されpresenseのバリデーションが走るようになったようです(https://github.com/rails/rails/issues/34454 )。
そのため、今回のケースではbuyer_idのほうにoptional: trueをかけてpresenseのバリデーションを追加しないように指定することが必要です。
こうしないとユーザー新規登録時と購入時にbuyerを入力してくださいと言われちゃいます。

models/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 :bought_items, class_name: 'Item', foreign_key: 'buyer_id'
  has_many :sold_items, class_name: 'Item', foreign_key: 'seller_id'
end

class_nameの記述をしました。
仕組みについては前回の記事を見てください。

itemsテーブルにseller_idカラムとbuyer_idカラムをinteger型で追加します。

ターミナル
$ rails g migration AddColumnToItems
db/migrate/20200818033036_add_column_to_items.rb
class AddColumnToItems < ActiveRecord::Migration[6.0]
  def change
    add_column :items, :seller_id, :integer
    add_column :items, :buyer_id, :integer
  end
end
ターミナル
$ rails db:migrate

これでカラムが追加されました。
ではデータベースを起動してみましょう。

ターミナル
$ rails s

ブラウザでlocalhost:3000にアクセスしてください。
スクリーンショット 2020-08-19 9.47.39.png
こんな画面になっているかと思います。
まずは新規登録でユーザーを作成してください。
その後、入力フィールドに商品名を入力して送信を押すと、テーブルにデータが保存されるはずです。
sequelProなどでテーブルの中身を見ると、seller_idのところにログインしているユーザーのidが入っていると思います。(僕はid:2のユーザーでログインしていたのでseller_id:2になっています)
スクリーンショット 2020-08-19 9.55.02.png

おわりに

ここまでの流れで問題がなければ、開発環境で実装できるのではないかと思います。

備忘録として書いていますが、以下少しだけ。
僕は新しいことを実装する前には簡単なミニアプリを作ってから実装するようにしているのですが、頭の整理にもなってていいなと思っています。
まだまだ初学者の域を抜けませんが、他の方の助けになりましたら幸いです。
ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0