###前提・実現したいこと
Ruby on rails 5で書籍を読みつつ簡易掲示板を写経しています。
モデルは使わず、コントローラーとビューのみをつかっていて、データはdata.txt
に保管しています。
そのときにどうしてもわからない部分があったため質問しました。
###発生している問題・エラーメッセージ
dengonban_controller.rb内の@dengon_data
というインスタンス変数があると思います。
この中には、JSON形式の投稿内容が入りますが、DengonbanController
のindexメソッド内での@dengon_data
の挙動が理解できません。
念のためですが、挙動を確認しつつ、理解できないところをあげていきます。
※今回聞きたいところは太字にしてあります。
request.post?
でリクエストがPOSTかどうか判別する(今回はPOSTだったとして進めます)- obj変数に、
MyDataクラス
でオブジェクトにした(←なぜこうするのか、理解できていない)投稿内容を入れる @dengon_data
に投稿があった時間をキーとして手順2で作ったオブジェクトを入れるdata.txt
に新しく投稿された内容を含めたデータを入れるために@dengon_data
をto_json
でJSON形式の文字列にするFile.write
を使い、data.txt
の内容を更新するJSON.parse(data)
でJSONを@dengon_data
に代入(なぜ@dengon_data
のままではいけないのか、理解できない)
###該当のソースコード
dengonban_controller.rb
ruby
1class DengonbanController < ApplicationController 2 layout "dengonban" 3 4 def initialize 5 super 6 7 begin 8 @dengon_data = JSON.parse(File.read("data.txt")) 9 rescue 10 @dengon_data = Hash.new 11 end 12 13 @dengon_data.each do |key, obj| 14 if Time.now.to_i - key.to_i > 24*60*60 15 @dengon_data.delete(key) 16 end 17 end 18 19 File.write("data.txt", @dengon_data.to_json) 20 21 end 22 23 def index 24 if request.post? 25 obj = MyData.new(message: params["msg"], namae: params["name"], mailaddress: params["mail"]) 26 @dengon_data[Time.now.to_i] = obj 27 data = @dengon_data.to_json 28 File.write("data.txt", data) 29 @dengon_data = JSON.parse(data) 30 end 31 end 32end 33 34class MyData 35 attr_writer(:name, :mail, :msg) 36 37 def initialize(message: msgs, namae: names, mailaddress: mails) 38 self.name = namae 39 self.mail = mailaddress 40 self.msg = message 41 end 42end
view/dengonban/index.html.erb
ruby
1<table class="form"> 2 <%= form_tag controller: "dengonban", action: "index" do %> 3 <tr> 4 <td>name:</td> 5 <td> 6 <%= text_field_tag("name") %> 7 </td> 8 </tr> 9 <tr> 10 <td>mail:</td> 11 <td> 12 <%= text_field_tag("mail") %> 13 </td> 14 </tr> 15 <tr> 16 <td>message:</td> 17 <td> 18 <%= text_area_tag("msg", "", {:size => "50x3"}) %> 19 </td> 20 </tr> 21 <tr> 22 <td></td> 23 <td> 24 <%= submit_tag("click") %> 25 </td> 26 </tr> 27 <% end %> 28</table> 29 30<table class="dengon"> 31 <tr> 32 <th style="width: 50%;">message:</th> 33 <th>name:</th> 34 <th>mail:</th> 35 <th>message:</th> 36 </tr> 37 <% @dengon_data.each do |key, obj| %> 38 <tr> 39 <td class="msg"><%= obj["msg"] %></td> 40 <td class="name"><%= obj["name"] %></td> 41 <td class="mail"><%= obj["mail"] %></td> 42 <td class="time"><%= Time.at(key.to_i) %></td> 43 </tr> 44 <% end %> 45</table>
view/layouts/dengonban.html.erb
ruby
1<!DOCTYPE html> 2<html> 3<head> 4 <title>伝言板</title> 5 <%= csrf_meta_tags %> 6 <%= stylesheet_link_tag("application", media: "all", "data-turbolinks-track": "reload") %> 7 <%= javascript_include_tag("application", "data-turbolinks-track": "reload") %> 8</head> 9<body> 10<h1 class="title">簡単伝言板</h1> 11<%= yield %> 12<div class="footer">copyright hogehoge</div> 13</body> 14</html>
routes.rb
ruby
1Rails.application.routes.draw do 2 get 'dengonban/index', to: "dengonban#index" 3 post 'dengonban/index', to: "dengonban#index" 4 5 get "helo/index", to: "helo#index" 6 post "helo/index", to: "helo#index" 7end
dengonban.scss
scss
1h1.title { 2 font-size: 20pt; 3 color: #999999; 4} 5 6.form { 7 margin: 50px 0; 8} 9 10.form tr td { 11 color: #999999; 12 padding: 0 10px; 13 font-size: 14pt; 14} 15 16th { 17 background: #999999; 18 color: #eeeeee; 19 font-size: 14pt; 20 padding: 2px; 21} 22 23.dengon tr td { 24 background-color: #eeeeee; 25 color: #666; 26 padding: 10px 5px; 27} 28 29td.msg, td.name, td.mail { 30 font-size: 12pt; 31} 32 33td.time { 34 font-size: 9pt; 35} 36 37div.footer { 38 border-style: solid; 39 border-width: 1px 0 0 0; 40 border-color: #999999; 41 margin: 50px 0 0 0; 42 padding: 3px 0 0 0; 43 color: #999999; 44 font-size: 12pt; 45 text-align: right; 46} 47
###試したこと
発生している問題・エラーメッセージの6番で言った「なぜ@dengon_dataのままではいけないのか、理解できない」について試したことがあります。
それは@dengon_data = JSON.parse(data)
を削除してdata.txt
に入る内容を見るというものです。その結果得られた文字列が下になります。
{1513499068=>#<MyData:0x000000000ca58c58 @name="s", @mail="s", @msg="s">}
謎の数列(恐らくタイムスタンプ)とMyData
とその後の記号、そのあとにはMyDataクラス
に渡した変数の内容が入っています。
このことから、@dengon_data
に新しく入った値はJSONの形式ではないからJSON形式の文字列にしたものをJSONに戻して代入しなければならないのかなあ、と考えていますが、あまり自信がありません。
これを試した結果、JSON形式にしたり、それを文字列にしたり戻したりしていてややこしいため、何をしているのか理解しきることができないのかなと考えています。
###補足情報(言語/FW/ツール等のバージョンなど)
Ruby on rails 5
追記
書籍のソースコード
上記のソースコードは私が書籍のコードを理解するために色々な編集を加えたものでした。質問と回答の食い違いを防ぐために、追記として書籍のコードを記述させていただきます。ここに記述されていないファイルのものは、上記と同じ内容のものです。
MyDataクラス
のinitializeメソッド
について、後述の私が参考にしている書籍で使用されるRubyのバージョンでは警告が発生しますが、これが書籍に載っている内容であることをあらかじめご理解お願いします。
dengonban_controller.rb
Ruby
1class DengonbanController < ApplicationController 2 layout "dengonban" 3 4 def initialize 5 super 6 7 begin 8 @dengon_data = JSON.parse(File.read("data.txt")) 9 rescue 10 @dengon_data = Hash.new 11 end 12 13 @dengon_data.each do |key, obj| 14 if Time.now.to_i - key.to_i > 24*60*60 then 15 @dengon_data.delete(key) 16 end 17 end 18 19 File.write("data.txt", @dengon_data.to_json) 20 21 end 22 23 def index 24 if request.post? 25 obj = MyData.new(msg: params["msg"], name: params["name"], mail: params["mail"]) 26 @dengon_data[Time.now.to_i] = obj 27 data = @dengon_data.to_json 28 File.write("data.txt", data) 29 @dengon_data = JSON.parse(data) 30 end 31 end 32end 33 34class MyData 35 attr_accessor(:name) 36 attr_accessor(:mail) 37 attr_accessor(:msg) 38 39 def initialize msg: msg, name: name, mail: mail 40 self.name = name 41 self.mail = mail 42 self.msg = msg 43 end 44end
書籍のタイトルについて
「質問への追記・修正、ベストアンサー選択の依頼」にて質問がありました、参考にしている書籍のタイトルについてですが、私が参考にしている書籍は「Ruby on Rails 5 超入門」という書籍で、発行日が2016年12月20日のものです。
どうか、よろしくお願いします