質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1409閲覧

データの型を見て、自動でコンポーネントを出力したい

nae_stage

総合スコア274

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2017/04/04 09:29

やりたいこと
オブジェクトのデータの型を見て、
「integer」ならスピンボタンがついたテキストボックスを
「datetime」ならカレンダーピッカーを
「string」ならただのテキストボックスを
自動で表示できるような仕組みを作ろうとしています。

やったこと・問題点
このサイトなどを見て、「datetime」や「integer」という型が存在することを確認し、
以下のような部分テンプレートを作成しました。
この部分テンプレートを各viewから呼び出して使用します。(「model」にはビューから渡ってきたデータが入ります)

ruby

1(pertial.html.erb) 2<% if model.class === "Integer" %> 3 スピンボタンがついたテキストボックスを表示 4<% elsif model.class === "Datetime" %> 5 カレンダーピッカーを表示 6<% elsif model.class === "String" %> 7 ただのテキストボックスを表示 8<% end %>

そして、以下のコマンドを実行し、画面を作成し、上記部分テンプレートを呼び出しました。

rails g scaffold todo name:string date:datetime number:integer price:decimal

ruby

1<%= render 'pertial', model: @todo.date %>

ところが、実行してもカレンダーピッカーが表示されませんでした。
同じように、スピンボタンがついたテキストボックスも表示されませんでしたが、
ただのテキストボックスは表示されました。

model.classの中身を見てみると、以下のように型が変化していました。
datetime ⇒ ActiveSupport::TimeWithZone
integer ⇒ Fixnum
string ⇒ 変化無し

そこで、部分テンプレートを下記のように変更しました。

ruby

1(pertial.html.erb) 2<% if model.class === "Fixnum" %> 3 スピンボタンがついたテキストボックスを表示 4<% elsif model.class === "ActiveSupport::TimeWithZone" %> 5 カレンダーピッカーを表示 6<% elsif model.class === "String" %> 7 ただのテキストボックスを表示 8<% end %>

しかし結果は変わらず、ただのテキストボックスしか表示できませんでした。

(1)なぜ型が変わるのか
(2)なぜ型が合ってるはずなのに、分岐を通り過ぎてしまうのか
(3)なぜStringだけうまくいくのか
(4)どうすればやりたいことが実現できるのか
お分かりの方、ご教授いただけませんでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

色々と間違っているので何から突っ込んだらいいか…
多分javascriptあたりからいらしたんでしょうrubyは別世界ですからね。
とりあえず質問に答える前に以下の前提を考慮してください。

1「datetime」や「integer」という型はDataBaseにおける型です。
参考サイトはあくまでDataBaseを作る際のデータの形式(型)を指定してるだけで
Rubyとはあまり関係ありません
※ちなみに型というのは数学的に言うと演算について閉じている(同じ型同士は足したり引いたりできる)と言う意味です。

Rubyに型といえば数字と文字あとはArrayとHashぐらいでしょうか?
ruby においてはミミズだってオケラだって、Integerだって(nilさえも)
みんなみんなClassです。methodが使えます。Classと型とは異なることをご理解ください。

2 部分テンプレートは通常このような用途には使いません
こういった場合Helper Methodを構築します。

3 rubyは===をあまり使いません、型を意識しないのが売りなので通常
==で事足ります。 ex 1=="1" => true

4 ruby で Class はイニシャルが大文字で表されます。
'String'とかで表されるわけではありません。
なので、"文字列".class==String => ture となります。

5 かえって混乱を招きますが===だとこういう面白いことが起こります。
"文字列"===String => false
String==="文字列" => true

これでnae_stage様の1−3の質問に答えられたと思います。

4に関しましてはcase when を使って(実はこの評価で===が使われます。)
helpers/application_helper.rbに

ruby

1def hoge_helper(model) 2 case model 3 when Fixnum 4 スピンボタンがついたテキストボックスを表示 5 when ActiveSupport::TimeWithZone 6 カレンダーピッカーを表示 7 when String 8 ただのテキストボックスを表示 9 end 10end

と追記してください
そしてviewで

ruby

1<%= hoge_helper(model) %>

と使うのがいいと思います。
私はこれをいつ使うのか見当がつきませんが…。

わからないことがあったらコメントください

投稿2017/04/04 16:32

編集2017/04/05 05:46
moke

総合スコア2241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nae_stage

2017/04/05 04:26

丁寧なご回答ありがとうございます!一からしっかり勉強する必要性を感じました・・・ いただいた回答について、さらに質問させていただけますでしょうか? (1)回答の1について Railsでは「datetime」型は無い・「datetime」クラスは無いため、 DBから「datetime」型として取得したデータは、 Railsによって自動的に、「datetime」を扱うのに適している「ActiveSupport::TimeWithZone」クラスのオブジェクトにされる という認識で合っていますでしょうか? (2)回答の5と、記載いただいたhelpers/application_helper.rbのコードについて "文字列".class===String => false であるならば、 case whenで評価すると、model.classの値がどの条件に当てはまらず、素通りしてしまうと思うのですが、 いかがでしょうか? 試しにいただいたcase whenで評価したコードを動かすと、全ての条件を素通りしてしまいました。 さらに、ifと==での評価に書き換えると、model.classの値がFixnumの場合、when Fixnumの分岐の中に入っていきました。 いただいた回答に対する私の解釈が間違っておりましたら、ご指摘いただけませんでしょうか? (3)これをいつ使うのかについて ASP.NET MVCで開発していた時、 データの型や、指定したDataTypeの値によって、 テンプレートビューを自動で選択し、コンポーネントを出し分けることができる仕組みがあったため (参考URL:http://www.buildinsider.net/web/bookaspmvc5/040402) 同じことができないかどうか、考えていた次第です。 以上、よろしくお願いします。
moke

2017/04/05 05:45

(1)あっています。しかしこれはRailsのversionによって変わりかねないので注意が必要です。 (2)ミスです回答を訂正しておきました。 (3)Railsはデータの変更をModelを中心にやります。DataBaseのデータタイプが付与されて構造もあらかじめ決まっているので動的に変わることは想定されていません。 例えば、データ構造が定まっていないJsonファイルやXmlファイル(はさすがにないか)だと こういった必要が出てくると思いますが、それは便利なライブラリがあったと思います。思い出したら追記します。
nae_stage

2017/04/05 06:25

ありがとうございます。大変勉強になりました。 「===」演算子・case式は、色々作ってみて慣れていこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問