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

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

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

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

Ruby on Rails

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

Q&A

解決済

2回答

415閲覧

送信された値が複数か、1つか知りたい

bouyomisan

総合スコア87

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2017/06/30 06:28

編集2017/07/04 01:29

入力欄が5つあるのですが、ユーザーは1つでも5つでも構わないという仕組みです。
複数の時は each を使い分解して処理し、1つの時はそのまま処理をしたいのですが、複数か1つかを見分ける方法がわからず困っています。どのようにしたら判別することができますか?

これが追記のコードです。if times.instance_of?(Array) の箇所をどうにかしたいです。

# instance_of?(Array) は必ず falseになってしまうため困っている times = params[:user][:note][:datetime] if times.instance_of?(Array) times.each do |time| if include_validate_time?(time) @user.notes.create(user_id: user_id.to_i, datetime: normalize_time(time)) normalize_time(time) end end else if include_validate_time?(times["0"]) @user.notes.create(user_id: user_id.to_i, datetime: normalize_time(times["0"])) end # datetimeフィールドで送信すると変になるから一つにまとめるためのメソッド def normalize_time(time) y = time["(1i)"] mo = time["(2i)"] d = time["(3i)"] h = time["(4i)"] mi = time["(5i)"] Time.new(y,mo,d,h,mi) end

ーーーーーーーーーー追記

ruby

1#日付を一つにした場合 2 3[1] pry(#<UsersController>)> times.is_a?(Hash) 4=> false 5[2] pry(#<UsersController>)> times.class 6=> ActionController::Parameters 7[3] pry(#<UsersController>)> times 8=> <ActionController::Parameters {"0"=>{"(1i)"=>"2017", "(2i)"=>"6", "(3i)"=>"2", "(4i)"=>"00", "(5i)"=>"00"}, "1"=>{"(1i)"=>"", "(2i)"=>"", "(3i)"=>"", "(4i)"=>"", "(5i)"=>""}} permitted: false> 9 10 11 12 13#日付を2つにした場合 14 15 16[5] pry(#<UsersController>)> times 17=> <ActionController::Parameters { 18"0"=> 19{"(1i)"=>"2018", "(2i)"=>"2", "(3i)"=>"1", "(4i)"=>"02",(5i)"=>"00"}, 20 21"1"=>{"(1i)"=>"2018", "(2i)"=>"1", "(3i)"=>"7", "(4i)"=>"01", "(5i)"=>"20"}} permitted: false> 22 23[6] pry(#<UsersController>)> times.class 24=> ActionController::Parameters 25[7] pry(#<UsersController>)> times.is_a?(Hash) 26=> false 27

変わらないですねー。どちらも Parameters というクラスになってます。あと関係あるかどうかわかりませんが、僕がform をいじってしまっているのもあって、paramas の中のキーに 0 とか 1 が紛れ込んでいるんです。

他の方は length とか size を使った例を教えてくださっているのですが、Parameters クラスには定義されてないようで使えないんです。

ーーーーーーーーーーさらに追記
pamrams に 0 とか 1 が自動で追記されることを利用して、
times.has_key?("1")
こうすればできました。が、汎用性も、拡張性も悪いのでもっとスマートな書き方が知りたいです!

ーーーーーーーーーーー最後の追記
完成しました!みなさまありがとうございました!
最後の ArgumentError はご覧の通り時間の入っている params に空のハッシュがあるからです。これは別のメソッドを使って取り除いています。

ruby

1pry(#<EventsController>)> time = Array(params[:user][:note][:datetime]) 2=> [<ActionController::Parameters {"(1i)"=>"2018", "(2i)"=>"3", "(3i)"=>"5", "(4i)"=>"03", "(5i)"=>"10"} permitted: false>, 3 <ActionController::Parameters {"(1i)"=>"", "(2i)"=>"", "(3i)"=>"", "(4i)"=>"", "(5i)"=>""} permitted: false>] 4 5pry(#<EventsController>)> Array(params[:event][:invites][:datetime]).each {|t| p normalize_time t} 62018-03-05 03:10:00 +0900 7ArgumentError: argument out of range 8

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

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

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

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

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

gouf

2017/06/30 07:21

問題としている部分のコードの開示は可能ですか
bouyomisan

2017/07/01 07:50

了解です!追記しました!
gouf

2017/07/02 00:20 編集

当該コード、「どのインスタンスであるか(instance_of?)」ではなく、「どのクラスであるか(is_a?)」とした場合に、動作は変わりますか? (hint: .class メソッドを用いて各オブジェクトのクラス名を確認することができます)
bouyomisan

2017/07/02 02:02

ダメでした・・コードの都合上質問文に追記させていただきました
guest

回答2

0

ベストアンサー

逆転の発想で、javascriptみたいに
timesをArrayにキャストしてしまえばいいと思います。
rubyも動的型付けですが、型を指定することができます。
そうすると条件分岐自体が不要になります。

ruby

1times = Array(params[:user][:note][:datetime]) 2times.each do |time| 3 if include_validate_time?(time) 4 @user.notes.create(user_id: user_id.to_i, datetime: normalize_time(time)) 5 normalize_time(time) 6 end 7end

投稿2017/07/03 04:28

編集2017/07/03 04:30
moke

総合スコア2241

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

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

bouyomisan

2017/07/04 01:31

すごいです!Array にキャストするという発想は全く思いつきませんでした・・・しかも条件分岐が消えるなんて・・ ありがとうございます。勉強になりました! もともとあった 0 とか 1 の数字は邪魔だったの削除しました。
guest

0

入力欄の各値を配列に格納し、rejectメソッドで値がblankの要素を除外する方法はいかがでしょうか?

ruby

1//tmpは各入力欄の値を格納した配列 2a = tmp.reject(&:blank?) 3if a.length == 1 4 // 1つのときの処理 5else 6 // 複数の処理 7end

投稿2017/06/30 06:40

nobu09

総合スコア33

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

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

bouyomisan

2017/07/02 02:01

その方法があったか!と思い試しましたが、ダメでした・・・ Parameters クラスには length も size も定義されてないようです
nobu09

2017/07/02 08:45

確かにそのコードですとParametersクラスになっているのでダメですね。 一旦Array.newで配列を作成し、それに代入し処理したらかがでしょうか?
nobu09

2017/07/02 09:18

と思ったら、0か1が必ず入るんですね。 では、とりあえず値をチェックする処理をメソッド化してしまえば、汎用性は高まると思います。 メソッドに切り出すことで、リファクタ時にそのメソッド内の修正のみに収まるので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問