Railsで試したかったオリジナルのアクション名でも動くのか!の巻

今回はRuby on Railsのお話です。

 

テックキャンプのカリキュラムに従って、または可読性としてアクション名がindexとかshowとかcreateとか決まり事に従って作って来ましたし、作ってこれました。

 

しかし、もっとこうしたい、細かくファイルの階層を作って行きたい!って時、indexは何度も使えない.....create内で同じ動きができるなら良いけど、別パターン動きをしたい時にコントローラーをもう1つ作るの嫌やわって事があるかも知れません。

 

そこで、疑問になって来たのが自分で考えたアクション名でもルーティングして、アクションして、何々してくれるのか?っと思い「試してみた!」というのが今回のアウトプットです。

 

今回設定してみた事はviewとしてブラウザにちゃんと表示されるか?です。

 

設定してみた内容は以下です

config/routes

Rails.application.routes.draw do
get 'otamesi', to: 'otamesis#tousaniyaiya'
end

 

app/cotrollers/otamesis

class OtamesisController < ApplicationController
def tousaniyaiya
end
end

 

app/views/otamesis/tousaniyaiya.html.erb

<h1>所詮この世はお試しさ</h1>

<h2>お父さん嫌い</h2>

 

f:id:kumo_sekine:20211209184620g:plain

otamesi

 

実際にオリジナルのアクション名でもちゃんとビューをGETして表示してくれました!

 

実験は以上で、スタジオにお返ししまーす。

 

 

ActiveHashで保存した内容をちゃんとViewするには?

ActiveHashはデータベースに保存する程でもない、決まったデータをモデルファイル内に保存してしまおうという大胆なRailsのGemです。

 

僕もなんでも酒屋でおなじみカクヤスのWEBアプリケーションでよくみる機能で、実際自分のオリジナルアプリに導入してみようという感じで鼻息が荒くなりました。

 

今回は間違えやすいViewの表示についてのアプトプットですが前置きが長い!

 

作業方法としては、まず主する、controllerやmodleなどなんやかんやを作ります

参考までに作ったなんやかんやです

 

コントローラーの記述!

class RoutinesController < ApplicationController
def new
@routine = Routine.new
end

def create
@routine = Routine.new(routine_params)
if @routine.save
redirect_to root_path
else
render :new
end
end

private

def routine_params
params.require(:routine).permit(:content,:calendar_id,:how_many)
end
end

母なるモデル!!

class Routine < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :calendar

validates :content, :how_many, presence: true

validates :calendar_id, numericality:{ other_than: 1 , message: "can't be blank" }
end

 

登録する為のView!!!

<div class="routines">
<h3>ルーティンワークを登録しよう</h3>
<div class="routines-new">
<%= form_with model: @routine, url:routines_path, local: true do |form| %>
<%= form.text_field :content, placeholder: "タイトル" ,class:"routines-title" %>
<%= form.collection_select(:calendar_id, Calendar.all, :id, :name, {},
  {class:"calendar-select"} ) %>
<%= form.text_field :how_many, placeholder: "分量" ,class:"how-many"%>
<%= form.submit "登録" ,class:"routine-btn"%>
<% end %>
</div>
</div>

 

以上がなんやかんやです。

 

導入方法としてはまず

Gemをbudleinstallしちゃいます。

その後、上記のモデルをrails g model routineしちゃいます。

 

modelディレクトリ内にActiveHashの為のファイルを作成します。

したのがこんな感じ

 

class Calendar < ActiveHash::Base

self.data = [
{ id: 1, name: '---' },
{ id: 2, name: '月1回' },
{ id: 3, name: '月2回' },
{ id: 4, name: '月3回' },
{ id: 5, name: '週1回' },
{ id: 6, name: '週2回' },
{ id: 7, name: '週3回' },
{ id: 8, name: '週4回' },
{ id: 9, name: '週5回' },
{ id: 10, name: '毎日' },
]

include ActiveHash::Associations
has_many :routine

end

 

個人的に重要と感じたのはclassのCalender < ActiveHash::Baseという継承する為の

記述でした。アソシエーションの記述です。何回も使えるという点は良いのですが、id1、id2と記述するのは本当に骨が折れます。複雑骨折です。

 

これらを設定すれば利用できるのですが、あとはバリデーションとしてのnumericalityはとりあえず設定しておいた方が良いので設定しました。数値かどうかを検証するバリデーションの一種だそうです。

 

っとざっくり紹介しましたが

 

ここからが本題です。

 

個人的に分かりにくかったポイントですが保存したアクティブハッシュのデータをViewに表示させる為の記述です。

 

モデル名.calendar_idと記述してもid番号が表示されてしまいます。

 

その為正しく表示させるにはメインとなるモデル名.ハッシュのモデルファイル名.nameとなるとの事です。最初に記載した内容を元にした記述だと「routine.calendar.name」となります。

 

ここが意外と分かりにくかったです。

 

calendar_id.nameでもだめです。

 

.nameの部分はどうやら以下のnameがカラムのようになっていてというかカラムだと思うのですがカラム名を記述する事でその中の値が表示される仕組みのようです。

{ id: 2, name: '月1回' },

 

まあそりゃそうですよね。Rubyのハッシュを使った記述なんですから、一周回ってRubyの理解が深まった感じがしました。

 

そちらはカラムの型ですか?私は関根と申します。

という事で本日もRuby on Railsのアウトプットです。

 

今回はデータベースのテーブルにまつわるカラムの型です。

データベースにはデータベースを分かる、見分ける為のテーブルなるものが存在します。テーブルがないデータベースは暗闇の世界を歩くものというかデータベースにデータが入れられません。

 

そのデータベースに保存されるデータをレコード

 

レコードに見出しをつけてくれるのがカラムだと思います。

 

カラム名は自由に決める事ができますので「絡む」とか「column」とか好きアルファヴェットでアレヴァ好き勝手に決められますが大体分かり易くします。

 

間違ってもスーパーウルトラトルネード....のようなものは卒業したので付ける事はありません。

 

ただこの自由に付けたカラムも数字だったり、文字だったり、時間だったり、長い文だったりと色々型があります。

 

型ある事でデータベースとの齟齬がなくなり、問題なく保存されるという事ですね。

 

どんな型があるかというと

 

大地の型

空の型

水の型

 

という感じの技の基本形のようなものではなく

 

string 短文型
text  長文型
integer 整数型

datetime 日時型

boolean 真偽値型

 

などがあります。もっとありますが使った事がありません。

 

以上で今日のアウトプットは終わりです。尻窄み落ちなしでごめんさい

 

そしてありがとう

1周回って理解が深まるHTMLのid属性とclass属性

JavaScriptでアプリを作る時にHTMLの記述でid属性が出てくるのでなんとなくid属性はJavaScriptの為のものって関連付けてしまっていましたが改めてHTMLの基礎を確認すると普通に『id属性は特定のHTML要素のみに対して名前を指定できる事ができる属性』と書いてありJavaScriptの為のidではなかったという事に気づきました。そこで改めて学習し直してみるとclassとidの違いって何?ってなりました。

 

最大の違いはclassは同じページ内で同じ名前を何度も利用できる。idは同じページに1回だけ。class="one"は何度もoneoneできるけどid="one"は1ページという世界ではonlyoneのようです。ちなみ唯一無二と相手を称賛する時にone & onlyと使うとカッコイイ気がします。自分もいつかは使うわれてみたいものです。ハイ。

 

そう考えると記述の意味合いもclass=固有ではない。id=固有という意味合いにも見えてきて見分けがつきやすくなりました。

 

この認識は更にJavaScriptにフィードバックして考えるとWEBページの一部を動かす事をメインの特徴とするJavaScriptはidの取得としてdocument.getElementbyidがよく使われている理由がわかってまいりまいした。

 

cssを読み込むためのセレクタが違うって事も今回の件でより理解できました。

clssは[ .○○ ]              idは[ # ]

 

 

誰が誰だか分からなくなるコメントアウト

今回は短めにアウトプット

 

HTMLやRubyやJSのコメントアウト方法がどれがどれだか分からなくなるのでアウトプットします。

 

HTMLは<!--で始まり-->で終わる

 

JavaScriptは/*で始まり*/で終わる(CSSも一緒)または//を先頭に入れるだけにすると//から以下が全てコメントアウトされる

 

そしてRubyは頭#のみ潔い

 

以上です。

 

親から子へ子から親へ引き継がれるルーティングネスト

Ruby on Railsで誰もがぶち当たる壁

 

showアクションってダジャレなのでは?って悩みながら日々過ごしていると思います。

 

実際にはレコードの内容を表示するアクションです。詳細とshow?内容が始まる=showが始まる?みたいな・・・・

 

そしてこのshowアクション内にコメント機能など、新たにレコード内容に紐つけされた。アソシエーションなデータを保存したりする時に当たらなるコントローラーを作成。コントローラーへのルーティングをする時に、元のレコードと関連づけて作らなくてはいけない。それがルーティングネスト構造!

resources :suzuki, only: [:index, :new, :create, :destroy, :show] do
resources :yamadas, only: [:create, :destroy]
end

 

resourcesにdoとendを足してrubyのwhileやeach分のような形にする構造にする事で今まで他人同士だったルーティング親子の契りをちぎる訳です。上では山田が鈴木の子供に養子縁組成立!

 

この時に散々悩んで苦しんだ内容が、子の中でデータの作成、削除を行う。アクションした際にshowアクションで指定したページ(show.html.erb)に戻ってくるにはどう記述すれば良いのか?

 

答えは以下の通りでした

 
 redirect_to "/suzukis/#{yamada.suzuki_id}"
 

 

子供のコントローラー内で行われるアクション作業をする際、親のshowのビューに戻すには親のURLと関連した子供に紐づいた親のIDと書くようです。なんとなく親子って考えると親を書いて子ってなりたくなり

 

suzuki.yamdaと書いたりしたり、他の方法試したり右往左往しました。このコントローラーからリダイレクトする時には子と紐ついている親と描くのが正しい様です。

 

 

 

FizzBuzzをWhileドにやってみた。

オヤジギャグを言っても問題ない年齢になってしまった事を謝罪します。

 

大変申し訳ございませんでした。

 

さてRubyを使ってFizz Buzzで使用したWhile分について自分なりに試して気づいた事をアウトプットします。

 

Fizz Buzzってなに?って調べたらウィキペディアに書いてありました。

詳しくはウィキペディアを参照してください。

 

今回は学習で行った内容でFizz Buzzについて掘り下げたい訳ではありません。

 

今回学習で出題された問題の条件としては以下

1. 1〜100までの数字をターミナルに出力してください。

2.「3の倍数」のときは数字の代わりに文字列でFizz

3.「5の倍数」のときは数字の代わりに文字列でBuzz

4.両方の倍数である「15の倍数」のときはFizzBuzzと出力してください。

 

まず学習で以上の条件を元にし作成した正解がこれ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  def fizz_buzz
    num = 1
    while (num <= 100) do
      if (num % 3 == 0) && (num % 5 == 0)
        puts "FizzBuzz"
      elsif (num % 3) == 0
        puts "Fizz"
      elsif (num % 5) == 0
        puts "Buzz"
      else
        puts num
      end

      num = num + 1
    end
  end

  fizz_buzz

 

今回気になって調べたり、色々試したりした事がwhile文の範囲や成立する為の記述です。

 

while文はdoからendの処理を指定した条件式まで繰り返すという式です。

 

2行目のnum=1ですがこれはnum=0ではダメなのか?

 

num=0からにしてしまうとその後whileの範囲指定のnumに0が代入されてしまう。

( 0 <= 100 )となってしまうので1からではなく0からFizzBuzzってしまうので101回目のプロポーズカウントされてしまうので上にあげた1の条件不成立となりました。

 

次が14行目のnum = num + 1が4行目ではなくなぜ条件分岐処理後なのか?

 

ここがwhile文を理解を深める重要なポイントでした。

 

今回ポイントになる事がnumが100になるまで繰り返す。という事のなので

4行目にnum = num + 1を記述してしまうとnumが最初に2から始まってからif条件分岐が始まり足されてしまうという事です。ちなみにnum = num + 1を書いておかないと数が増えていかないので永遠と1の処理をくりかえしいずれ朽ちて灰になります。

 

1から数字が始まって数字がFizzBuzzなの?Fizzなの?Buzzなの?それ以外なの?の結果(値)を出力して次の数字にカウントを増やしてまたwhileの処理を100まで繰り返す。その為にnum = num + 1が最後に必要だったという訳です。

 

そんなの当たり前じゃん?って思うかもしれませんが、プログラマー初心者や未経験者人にとってはその当たり前が当たり前ではなく、それを説明したりアウトプットしている人がなぜかいないのでアウトプットしてみました。

 

実はいたらごめんなさい。