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

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

ただいまの
回答率

90.34%

  • Ruby on Rails

    7677questions

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

  • JSON

    1235questions

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

  • POST

    242questions

    POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

  • Cisco

    100questions

    シスコ(Cisco Systems,Inc.)は、アメリカ合衆国に本社を置く、世界最大のコンピュータネットワーク機器開発会社及び同社の製品

  • GET

    95questions

    GETとはHTTPが対応するリクエストメソッドの一つです。クライアントからサーバーへ送られたURLパラメータのデータを取得する時必要がある時に使われます。

railsでjsonを取得することができません

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 282

kozica

score 41

 前提・実現したいこと

cisco MerakiのScanning APIを使いPOSTされたjson形式のデータをRailsで取得したいです。

しかし、そのjsonを取得できません
rails側でエラーは出てないのですが、Merakiダッシュボードの方でエラーが表示されてます。

当方初心者なためそもそもrailsでjsonの取得のコーディングがあってるか怪しいです。

 発生している問題・エラーメッセージ

Merakiダッシュボードで表示されてるエラー内容

”Did not match validator: http://wex01.cloud24.jp/personal_logs”

#app/controllers/personal_logs_controller.rb
validator ='xxxxxxxxxxxxxxxx'
secret = 'xxxxxxxxxx'

class PersonalLogsController < ApplicationController
  skip_before_action :verify_authenticity_token
  before_action :set_personal_log, only: [:show, :edit, :update, :destroy]

  def presenceapi
    if request.post?
      map = JSON.parse(params[:data]).with_indifferent_access
      if map[:secret] == secret
        map[:probing].each do |p|
          PersonalLog.create(ap_mac: p[:ap_mac], client_mac: p[:client_mac],
                          last_seen: DateTime.parse(p[:last_seen]),
                          rssi: p[:rssi])
        end
        render :text => '' and return
      else
        Rails::logger.warn("*** MERAKI req with bad secret '#{map[:secret]}'")
        rails 'access denied'
      end
    else
      render :text => MERAKI_VALIDATOR
    end
  end
end
#config/routes.rb
Rails.application.routes.draw do
  match 'personal_logs', :to => 'personal_logs#presenceapi', :as => :personal_logs, :via => [:get, :post]
end
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

Rails 5.1以降render :text =>''廃止されました

render :plain => MERAKI_VALIDATOR


を利用してください

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 10:02

    回答ありがとうございます!
    上記の通り textからplainに変更して実行したところ
    Validated http://wex01.cloud24.jp/personal_logs
    と表示されました。
    これは成功したということでしょうか?

    キャンセル

  • 2018/07/26 10:03

    また、昨日も回答して頂き本当にありがとうございます!!

    キャンセル

  • 2018/07/26 10:10

    rails側で下記エラーが出力されました
    ```
    Started POST "/personal_logs" for 127.0.0.1 at 2018-07-26 10:07:07 +0900
    (0.2ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
    LoadError (Unable to autoload constant PersonalLog, expected /home/ユーザ名/workspace/working/webex/app/models/personal_log.rb to define it):
    ```
    app/models/personal_log.rbに問題があるようですが、ここには何も書いてないのですが、何か記述が必要なのでしょうか?

    キャンセル

  • 2018/07/26 10:35

    エラーとしては、「定数PersonalLog(たぶんクラス)が見つからない」
    なので、
    「PersonalLog」でgrep検索して誰が参照してて、どこにあるのか
    を把握することが対処の第一歩

    キャンセル

  • 2018/07/26 10:51

    $grep PersonalLog
    を実行したところ、処理が多いせいなのかずっと処理中なようで結果が得られてないです。
    他に調べたところ、PersonalLogの記述ミスがないか調べてみます

    キャンセル

  • 2018/07/26 10:58

    git grep -w PersonalLog

    gitのgrepコマンドの方が検索対象絞れて速いかもしれませんね

    キャンセル

  • 2018/07/26 11:11

    下記結果になりました。
    $ sudo git grep -w PersonalLog
    fatal: Not a git repository (or any of the parent directories): .git

    キャンセル

  • 2018/07/26 16:49

    ありゃgitで管理してるわけじゃなかったのですね
    申し訳ございません

    キャンセル

checkベストアンサー

0

cisco Merakiはよく知らないのですが、Merakiダッシュボードに表示される(はずの)Validatorを、GETリクエストの際に返してやる必要があるようです。
「Did not match validator」というメッセージの意味はそういうことだと思われます。

書かれているコードの場合、presenceapiメソッドの最後のrender :text => ''render :plain => ''''を、空文字ではなくValidatorを文字列として記述するようにしてみるとよさそうです。
※確かに別回答でasmさんが書かれてたようにrender :plainが正しそうですね。


初心者の方がいきなりいろいろやろうとすると難しそうなので、まずは単純にPOSTで送られてきたJSONデータを保存するところまでする、という想定で、イチから行うよう整理してみます。

rails newから始めると、だいたい以下のような流れになるかと思います。

rails new scanning-app
cd scanning-app
rails g scaffold Event data:text
rails db:migrate

ここでscaffoldで作っているのは、dataというカラムにJSONのオブジェクトのうち、data:というキーの値を全部テキストとして保存する、という想定です。リクエストを受け取るURLが/eventsだそうなので、モデルはEvent、コントローラーはEventsControllerにしています。

こんな感じで用意して、app/controller/events_controller.rbは、

class EventsController < ApplicationController
  skip_before_action :verify_authenticity_token

  VALIDATOR = "xxxxx"

  def index
    render :plain => VALIDATOR
  end


  def create
    @event = Event.new(data: params[:data].to_s)

    if @event.save
      render :plain => "OK"
    else
      render :plain => "NG"
    end
  end
end

みたいにします。VALIDATORは正しい値を入れてください。

ローカルで確認する場合は、

rails server

でサーバを立てると、http://localhost:3000/で立ち上がるはずです。
これで、curlを使って(curlがなければインストールしておいてください)、

curl http://localhost:3000/events

とすると、VALIDATORの文字列が帰ってくるはずです。同様に、POSTについては、

curl -X POST -H "Content-Type: application/json" -d '{"secret":"xxxx","version":"2.0","type":"DevicesSeen","data":{"a":"bbb"}}' http://localhost:3001/events

みたいな感じで適当にJSONを作ってPOSTリクエストを行ってみると、data:の値が保存されることが開発環境で確認できるかと思います。

これをproductionのサーバに持っていって、動作するのを確認したあとで、それからsecretの値チェックとか、data:の値をさらに項目ごとに分けてDBに保存するようにする、といったことを試してみるとよいかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 09:19

    回答ありがとうございます。
    仰られたようにpresenceapiメソッドの最後の下記のように変更しましたが、同じ「Did not match validator」と表示されてしましました。
    render :text => MERAKI_VALIDATOR

    キャンセル

  • 2018/07/26 09:32

    初心者なりに原因を考えてみましたがどうでしょうか?
    ・def presenceapiメソッドはコントローラーに記述してますが、記述場所としてあってますか?
    ・presenceapi.html.erbにはなにか呼び出しなどの記述は必要ですか?
    ・models/personal_logのほうにpresenceapiメソッドを記述する必要はないですか?

    また、routes.rbも書き直したので投稿を修正致します。

    キャンセル

  • 2018/07/26 09:44

    cisco merakiのScanning APIについての説明ページを記載しておきます。
    返す形式としてjsonになってないからなのかなと思ったですがどうでしょうか
    https://www.cisco.com/c/m/ja_jp/meraki/documentation/mr/monitoring-and-reporting/location-analytics.html

    キャンセル

  • 2018/07/26 10:52

    https://files.mtstatic.com/site_5814/2616/0?Expires=1532572128&Signature=hV3eDGD2EIMDcA0UfGSOS2~8EX7FP0MYfCojrEDyUU-woTr45cme7v2j1tXu5lEu4u9uyRs1bHdt43ozHAwJRMHfK~q40LORUSahEjLv6d~rmQ4H5PV-e1r9stKNWHI6LMx~L8l1AyFCcCr61bFREgDm6ycE7EgYj5FaQVSXXP0_&Key-Pair-Id=APKAJ5Y6AV4GI7A555NA を見ると、最初に返す値はPOSTのJSONとは関係なさそうです

    キャンセル

  • 2018/07/26 10:55

    確かにそのようですね!
    今は下記エラーと戦っております。
    Started POST "/personal_logs" for 127.0.0.1 at 2018-07-26 10:07:07 +0900
    (0.2ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
    LoadError (Unable to autoload constant PersonalLog, expected /home/ユーザ名/workspace/working/webex/app/models/personal_log.rb to define it):

    キャンセル

  • 2018/07/26 13:49

    うーん、personal_logs_controller.rbですが、これってどうやって作られましたか? scaffoldしたんでしょうか。
    ActiveRecordのモデルとして、PersonalLogクラスではなくPresenceクラスを使いたいのは何か理由があるんでしょうか。

    キャンセル

  • 2018/07/26 13:53

    personal_logs_controller.rbはscaffoldして作ったと記憶してます。
    PersonalLogクラスではなくPresenceクラスを使いたい理由はないので、変える必要があるならすぐに変えます。
    当方初心者なためそこらへんの関係性もまだ完璧に把握できておりません、、、

    キャンセル

  • 2018/07/26 14:16

    ご指摘にあったとおりPresence.createをPersonalLog.createに変更したのですが、同じエラーが返って来てしましました。

    キャンセル

  • 2018/07/26 14:20

    エラーで指摘されている行をみてみると、
    ```
    map = JSON.parse(params[:data]).with_indifferent_access
    ```
    この行を指摘されてるのでこの辺に原因があるのかなと思っています。
    models/personal_log.rbには何か記述することがあるのでしょうか?
    今何も記述してないのでそれも原因かと考えられます

    キャンセル

  • 2018/07/26 14:39 編集

    あ、申し訳ありません
    エラー内容が違いました。
    Processing by PersonalLogsController#presenceapi as HTML
    Parameters: {"version"=>"2.0", "secret"=>.......


    "rssi"=>17, "ipv6"=>nil, "manufacturer"=>"Rivet Networks"}]}}}
    Completed 500 Internal Server Error in 8ms (ActiveRecord: 0.8ms)
    TypeError (no implicit conversion of ActionController::Parameters into String):
    app/controllers/personal_logs_controller.rb:12:in `presenceapi'
    上記エラー内容となっております

    キャンセル

  • 2018/07/26 19:52

    その辺から違っているのであれば根本的になんとかした方が良さそうですね…。
    回答の方にあとで追記します。

    キャンセル

  • 2018/07/27 16:29

    ものすごく細かく説明して頂き本当にありがとうございます!(泣)
    無事うまく動いてeventテーブルにデータが格納されるようになりました!

    本当にありがとうございました!!

    キャンセル

  • 2018/07/27 17:29

    無事に動いてよかったですね!
    もっともこれは最初のとっかかりで、最後のところに書いた通り、dataの項目に分けて保存したり、secretやtypeのチェックをしたり等が必要になるかと思いますが、一回動くところまでいけば、続きの作業もやりやすくなるかと思います。がんばってください。

    キャンセル

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

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Ruby on Rails

    7677questions

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

  • JSON

    1235questions

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

  • POST

    242questions

    POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

  • Cisco

    100questions

    シスコ(Cisco Systems,Inc.)は、アメリカ合衆国に本社を置く、世界最大のコンピュータネットワーク機器開発会社及び同社の製品

  • GET

    95questions

    GETとはHTTPが対応するリクエストメソッドの一つです。クライアントからサーバーへ送られたURLパラメータのデータを取得する時必要がある時に使われます。