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

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

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

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Q&A

解決済

1回答

2576閲覧

railsで送られてくるjsonデータの特定の値を配列として取得したい

kozica

総合スコア58

Ruby on Rails 5

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

0グッド

0クリップ

投稿2018/07/30 09:33

Railsで送られてくるjsonデータを受け取りその中からclientMacキーの値をすべて配列で取り出したいです

送られてきたjsonから"clientMac"を配列で取得するには下記のように書けばいいとわかるのですが、
下記の"hash"の部分が何を入れればいいのかがわかりません。
jsonデータを定数で定義していないのでどういう形で呼び出しすればよいのか

送られてくるjsonデータ { "apMac": <string>, "apTags": [<string, ...], "apFloors": [<string>, ...], "observations": [ { "clientMac": <string>, "ipv4": <string>, "ipv6": <string>, "seenTime": <string>, "seenEpoch": <integer>, "ssid": <string>, "rssi": <integer>, "manufacturer": <string>, "os": <string>, "location": { "lat": <decimal>, "lng": <decimal>, "unc": <decimal>, "x": [<decimal>, ...], "y": [<decimal>, ...] }, },... ] }
hash['observations'].map { |o| o['clientMac'] } #=> ["","","","",.....,""](Macアドレスが格納)

この上記の"hash"さえ何を入れればいいかわかれば解決するのですがお力を貸して頂きたいです。

送られてきたjsonデータをeventsテーブルのdataカラムに格納する記述は下記のようにしています

ruby

1#app/controllers/events_controller.rb 2def create 3 @event = Event.new(data: params[:data]) 4 if @event.save 5 render :plain => "OK" 6 else 7 render :plain => "NG" 8 end 9end 10

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

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

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

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

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

guest

回答1

0

ベストアンサー

これですが、

ruby

1hash = JSON.parse(params[:data])

ではなかったでしょうか?

投稿2018/07/30 09:56

編集2018/07/31 03:26
takahashim

総合スコア1877

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

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

kozica

2018/07/31 01:00

やはりそうですよね。 この場合だと、@eventということですよね。 とすると、Railsの依存関係などが把握できていないので、それで呼び出しに失敗しているのかもしれないです。 流れとしては、 jsonデータ受け取る→createメソッドでjsonデータが@eventに定義されテーブルに格納 つまり@event→jsonデータという認識で大丈夫でしょうか? この認識で合ってるなら、 @event[:observations].map {|o| o['clientMac'] } でjsonデータの'clientMac'キーの値を配列化できないのはなぜでしょうか?
takahashim

2018/07/31 03:27

うーん、「呼び出しに失敗しているのかもしれない」「配列化できない」というのでは何が起こっているのかよくわからないので、具体的にどういうエラーが出るのか、どういう挙動になるのかを書かれた方がよいかと思いました。 あと、「@event→jsonデータ」というのはどういう意味でしょうか? 「jsonデーター>@event」(JSONから@eventを作る)なら分かるのですが。 @eventのdataには、現状では素の文字列が保存されているはずです。
kozica

2018/07/31 03:32

説明が下手ですいません。 つまり下記のように加えて def create @event = Event.new(data: params[:data])  hash = JSON.parse(params[:data]) if @event.save そしてeventモデル?で下記を記述するのでしょうか? hash['observations'].map { |o| o['clientMac'] } viewで上記結果の配列を表示するにはこれでいいのでしょうか?
takahashim

2018/07/31 04:10

DBに保存するにはモデルにいろいろ記述することになりますし、ブラウザに表示するだけならビューをいじることになるかと思います。 素朴には、 render :plain => "OK" のところを、 render :plain => hash.to_s とかにすればブラウザに文字列で表示されることになります。 hash.to_sの代わりに hash['observations'].map { |o| o['clientMac'] }.to_s とかでもよいですけど。 とはいえ、これはJSON APIのレスポンスになる(JSONをPOSTしてきたサーバに返す)ので、そもそもブラウザで表示するのがいいのかは微妙ですが…。
kozica

2018/07/31 05:12 編集

なるほど、、、 丁寧にありあとうございます! 質問が回りくどかったのかもしれません。 本来は、personal_logsテーブルの"macaddr”カラムのMACアドレスと、ここで記載した hash['observations'].map { |o| o['clientMac'] }というwifi proveしたMACアドレスの配列を照合して、合致するpersonal_logsテーブルの"data"カラムに格納されている個人情報を出力するようにしたかったんです。 しかし、hash['observations'].map { |o| o['clientMac'] }がどう呼び出し?定義?していいのかわからなかったため、ちゃんとできているか確認のためにという意味でviewで表示させたいと記載しておりました。 ここの投稿はこちらをベストアンサーに選ばさせて頂き、上記内容で新たに投稿し直します。
kozica

2018/08/01 05:51 編集

すいません。 hash = JSON.parse(params[:data]) これはどこに記述すればよいのでしょうか? indexに記述してもエラーが出てきてしまいました def index @hash = JSON.parse(params[:data].to_s) end そして、 index.html.erbに <p><%= @hash %></p> と記述しましたが下記エラーが出ました。 TypeError (no implicit conversion of nil into String): app/controllers/events_controller.rb:10:in `index'
takahashim

2018/08/01 06:21

controller(この例ならcreate)に書けば、hashという変数に代入されるはずですよ。
kozica

2018/08/01 06:34

def create @event = Event.new(data: params[:data].to_s) @hash = JSON.parse(params[:data].to_s) createに上記のように書き加えて実行したところそれぞれで下記エラーがでました。 @event処理でのエラー Completed 500 Internal Server Error in 6ms (ActiveRecord: 0.9ms) @hash処理でのエラー JSON::ParserError (765: unexpected token at
kozica

2018/08/01 06:35

@eventのエラーは@hashの有無でエラーが出てきます
takahashim

2018/08/01 06:40

params[:data].to_sはto_sが不要な気もしますが、とにかくJSON::ParserErrorというのはJSONとして壊れてるデータになっているということですよね。params[:data]が正しく取れてるかどうか確認してみるとよさそうです。
kozica

2018/08/01 07:09

@eventは@hashのコード消せば正常に動き、あるとエラーになるので干渉しているようです。 また、@event単体のときはparams[:data]が正しく取れているので、そこは大丈夫かと思います。
kozica

2018/08/01 08:33 編集

JSON.parse消してみます
kozica

2018/08/01 07:34 編集

JSON.parseを消して処理はうまく動きました。 def create @event = Event.new(data: params[:data].to_s) @hash = params[:data].to_s この@hashが正しく取れているか確認するためにはどうすればいいでしょうか?
takahashim

2018/08/01 17:39

何が正しいのかよくわからないので確認方法もよくわからないのですが、そもそも `params[:data].to_s` の値はJSONになっているのでしょうか(JSONとしては壊れているのではないでしょうか)。 JSONとして正しいかどうかは、例えばjqコマンドがあれば確認できます。
kozica

2018/08/02 01:19 編集

{ "version":"2.0", "secret":<string>, "type":<event type>, "data":<event-specific data> } 上記の形で送られてきて、params[:data].to_sでdataのみ取得しています。 dataの中身は下記のようになってます。 { "apMac": <string>, "apTags": [<string, ...], "apFloors": [<string>, ...], "observations": [ { "clientMac": <string>, "ipv4": <string>, "ipv6": <string>, "seenTime": <string>, "seenEpoch": <integer>, "ssid": <string>, "rssi": <integer>, "manufacturer": <string>, "os": <string>, "location": { "lat": <decimal>, "lng": <decimal>, "unc": <decimal>, "x": [<decimal>, ...], "y": [<decimal>, ...] }, },... ] } 現状、@hashには上記apMacから始まるデータが入ってる?定義されているという認識で大丈夫でしょうか? 正しく取れているかとは、上の一文になっているかどうかという意味合いでした。 私はその確認方法の手段としてviewで表示させてみようとしていました。 jqコマンドでrailsで取得したjsonファイルがどこにあるのかわからないので調べてみます。 本当に説明が下手で申し訳ないです
takahashim

2018/08/02 03:48

上に書かれているのは期待するフォーマットで、生データではないですよね。 また、viewに表示させるというのは、APIサーバへの応答で、人が確認できるものではないでしょうか? データベースに保存されていたのなら、それが確認できないでしょうか。 また「この上記の"hash"さえ何を入れればいいかわかれば解決するのですがお力を貸して頂きたいです。」という当初の質問とはだいぶかけ離れてしまっているように思いました。
kozica

2018/08/02 05:54

「フォーマットであり生データではない」なるほどです。 「人が確認できるものではないのか?」確認不可能とは知らなかったです。 「データベースに保存されたものを確認」それは可能です。ただ送られてきたデータに対して処理しようとしていたので見ていませんでした。しかし、テーブルに格納してのち最新のレコードに対して処理するようにアプローチを変えるのでそれでいきます。
takahashim

2018/08/02 13:53

「生データではない」というのは、例えば「[<string, ...],」という文字列そのものが送られるのではなく、実際には「"xxxxx","yyyyy",」といった送られているわけですよね。そして、JSON::ParserErrorが出るという問題を解決するには実際に使われている文字列を見ないと判断しづらいかと思います。 「確認不可能」というのは、APIサーバからのリクエストに対するレスポンスはAPIサーバに送られるものですよね。通信をなんとかしてキャプチャする等すれば見られますが、あまり簡単ではないです。
kozica

2018/08/03 02:08

そうだったのですね。 丁寧に説明して頂きありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問