LoginSignup
5
4

More than 5 years have passed since last update.

会計ソフトを作ってみよう

Last updated at Posted at 2014-09-08

はじめに

会計ソフトみたいなものを作ってみようと思い、少し着手し始めました。今回はnested_formを試したので、それを紹介したいと思います。

やってみたこと、課題、参照したサイトなどを紹介します。

nested_form.gif

やってみたこと

次のコマンドを実行しました。

$ rails new sample_app
$ cd sample_app
$ vim Gemfile
$ bundle install
$ rails generate scaffold Entry date:date comment:text
$ rails generate scaffold Debit name:string money:integer entry_id:integer
$ rails generate scaffold Credit name:string money:integer entry_id:integer
$ rake db:migrate
$ vim app/assets/javascripts/application.js
$ vim app/models/entry.rb
$ vim app/models/debit.rb
$ vim app/models/credit.rb
$ vim app/controllers/entries_controller.rb
$ vim app/views/entries/_form.html.erb

編集対象のファイルはrailsコマンドで自動生成されます。編集対象のファイルはvimコマンドを実行したところです。(実際には何度もvimコマンドを実行することはありません。vimのノーマルモードで:e {file}とタイプすれば、ファイルを編集することができます。)

まずは、Gemfileを編集します。次の行を追加します。

gem 'nested_form'

次に、application.jsを編集します。次の行を追加します。

application.js
//= require jquery_nested_form

モデル間の関連は次のように実装します。

entry.rb
class Entry < ActiveRecord::Base
  has_many :credits
  has_many :debits
  accepts_nested_attributes_for :credits, allow_destroy: true
  accepts_nested_attributes_for :debits, allow_destroy: true
end
debit.rb
class Debit < ActiveRecord::Base
  belongs_to :entry
end
credit.rb
class Credit < ActiveRecord::Base
  belongs_to :entry
end

Strong Parametersというのがよく分かっていないのですが、ビュー側でentryが参照しているdebits, credits(に含まれるオブジェクト)の属性にアクセスするためにStrong Parametersを使っているようです。

これらを実装するために、コントローラーに実装を追加します。

entries_controller.rb
class EntriesController < ApplicationController

(中略)

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_entry
      @entry = Entry.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def entry_params
      params.require(:entry).permit(:date, :comment, debits_attributes: [:name, :money, :entry_id, :_destroy], credits_attributes: [:name, :money, :entry_id, :_destroy])
    end
end

ビューは次のように実装しました。

_form.html.erb
<%= nested_form_for(@entry) do |f| %>
  <% if @entry.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@entry.errors.count, "error") %> prohibited this entry from being saved:</h2>

      <ul>
      <% @entry.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :date %><br>
    <%= f.date_select :date %>
  </div>
  <div class="field">
    <%= f.label :comment %><br>
    <%= f.text_area :comment %>
  </div>
  <div class="field">
    <%= f.fields_for :debits do |debit| %>
      <%= debit.text_field :name %>
      <%= debit.text_field :money %>
      <%= debit.link_to_remove "Remove this debit" %>
    <% end %>
    <p><%= f.link_to_add "Add debit", :debits %></p>
  </div>
  <div class="field">
    <%= f.fields_for :credits do |credit| %>
      <%= credit.text_field :name %>
      <%= credit.text_field :money %>
      <%= credit.link_to_remove "Remove this credit" %>
    <% end %>
    <p><%= f.link_to_add "Add credit", :credits %></p>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

ここまでで冒頭のgifのような機能が実現されると思います。

課題

newとeditで同じ_form.html.erbを使っているので、更新しただけで、データが追加されてしまいます。

ほかにもたくさん課題がありそうです。。。

よく分かっていないのですが、debits, creditsのentry_idがなぜか自動で更新されました。どうやって更新しようか悩んでいたのですが、自動で更新されて少し驚きました。なぜなんでしょうか?

参照

5
4
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
5
4