americandog1993の日記

プログラマー歴半年のメモ

マイ家計簿アプリを作る①

思い立ったが吉日。

概要

  • ユーザー登録は後回し。自分だけ使えるようにしてみる。
  • とりあえず金額入力して保存できるようにする。
  • 合計支出を表示してみる。
  • デザインも後回し。

環境

  • Cloud9 RubyonRails
  • Ruby 2.3.0
  • Rails 5.0.0.1

Gemfile

source 'https://rubygems.org'

gem 'rails',        '5.0.0.1'
gem 'bcrypt',       '3.1.11'
gem 'puma',         '3.4.0'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.0.0'
gem 'coffee-rails', '4.2.1'
gem 'jquery-rails', '4.1.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.4.1'

group :development, :test do
  gem 'sqlite3', '1.3.11'
  gem 'byebug',  '9.0.0', platform: :mri
end

group :development do
  gem 'web-console',           '3.1.1'
  gem 'listen',                '3.0.8'
  gem 'spring',                '1.7.2'
  gem 'spring-watcher-listen', '2.0.0'
end

group :production do
  gem 'pg', '0.18.4'
end

取り込む。

$ bundle update
$ bundle install

ログイン

Sessionコントローラを作る。

$ rails g controller Sessions new
# sessions_controller.rb

class SessionsController < ApplicationController
  def new
  end
  
  def create
    user = User.find_by(name: params[:session][:name])
    if user && user.authenticate(params[:session][:password])
      session[:user_id] = user.id
      redirect_to user
    else
      render 'new'
    end
  end
end
#new.html.erb
<h1>Log in</h1>
<%= form_for(:session, url: login_path) do |f| %>

  <%= f.label :name %>
  <%= f.text_field :name %>

  <%= f.label :password %>
  <%= f.password_field :password %>

  <%= f.submit "Log in"%>
<% end %>

ログイン周りの便利メソッドを定義しておく。

#sessions_helper.rb

module SessionsHelper

  def log_in(user)
    session[:user_id] = user.id
  end

  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !current_user.nil?
  end
end

ユーザ

とりあえずUserモデル作る。

$ rails g model User name password_digest
$ rails db:migrate
#user.rb

class User < ApplicationRecord
    has_many :kakeibos
    has_secure_password
end

自分を登録しておく。

$ rails c
> User.create(name: "americandog", password: "foobar")

Userコントローラとビューも。

$ rails g controller Users new create show
#users_controller.rb

class UsersController < ApplicationController
  def new
  end

  def create
  end
  
  def show
    @user ||= User.find_by(id: session[:user_id])
    if !@user.nil?
      @total = 0
      @user.kakeibos.each do |k| @total += k.spending end
      render 'show'
    else
      redirect_to login_path
    end
  end
end
# show.html.erb

合計支出:<%= @total %>円
<ul>
<% @user.kakeibos.each do |k| %>
<li><%= k.spending %>円</li>
<% end %>
<li>
  <%= form_for [@user, @user.kakeibos.build] do |f| %>
  <%= f.label :spending %>
  <%= f.number_field :spending %>
  <%= f.submit %>
  <% end %>
</li>
</ul>

newとshowは今は手をつけない。

家計簿

$ rails g model Kakeibo spending:integer user:references
$ rails db:migrate
#kakeibo.rb

class Kakeibo < ApplicationRecord
  belongs_to :user
  validates :spending, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
end

続いてコントローラ。

$ rails g controller Kakeibos
#kakeibos_controller.rb

class KakeibosController < ApplicationController
  def create
    @user = User.find(params[:user_id])
    @kakeibo = @user.kakeibos.create(kakeibo_params)
    redirect_to user_path(@user.id)
  end
  
  private
    def kakeibo_params
      params[:kakeibo].permit(:spending)
    end
end

Herokuデプロイ

Herokuにあげたい場合。

$ git init
$ git add -A
$ git commit -m "First Commit"
$ heroku create
$ git push heroku master
$ heroku run rake db:migrate
$ heroku run rails c
> User.create(name: "americandog", password: "foobar")

今後

続きは次回。
あとやるべきことは・・・

  • デザインをBootStrapで整える。
  • 月単位・日単位で管理できるようにする。
  • ユーザ登録機能の実装。

現時点の課題はこんなものだろうか。