Zach Bryant
Zach Bryant

Reputation: 41

Rails: How to store a JSON object from a form and query it?

I am new to rails and am in need of help. I want my new post form to allow users to copy and paste the text from a JSON file into a text_area and have it stored as a JSON object in my Postgresql database. Then I want to be able to query the JSON object in the rails console or just in psql.

Here is my form:

<h1>New Post</h1>
<hr>

<div align="center"><%= form_for (@post) do |f| %>
    <div class="field">
        <%= f.label :title %>
        <%= f.text_field :title, :required => true %>
    </div>
    <br>
    <div class="field"> 
        <%= f.label :description %>
        <%= f.text_area :description, :required => true %>
    </div>
    <br>
    <div class="field">
        <%= f.file_field :json, :required => true %>
        <%= f.hidden_field :json_cache %>
    </div>
    <br>
    <div class="field">
                <%= f.label "JSON" %>
                <%= f.text_area :data, :required => true %>
        <%= f.hidden_field :user_id , :value => current_user.id %>
        </div>
        <br>
    <%= f.hidden_field :user_id , :value => current_user.id %>

    <div class="actions">
        <%= f.submit %>
    </div>
<% end %></div>

Here is my posts controller:

class PostsController < ApplicationController
  def edit
    @post = Post.find(params[:id])
  end
  def update
    @post = Post.find(params[:id])
    @post.update_attributes(post_params)
    redirect_to post_path(@post)
  end
  def new
    @post = Post.new
    @post.user_id = current_user.id
  end

  def index
    @posts = Post.all
  end

  def show
    @post = Post.find_by_id(params[:id])
  end

  def create
    @post = Post.new(post_params)
    if @post.save
        flash[:success] = "Success!"
        redirect_to post_path(@post)
    else
        flash[:error] = @post.errors.full_messages
        redirect_to new_post_path
    end
  end
  def destroy
    @post = Post.find(params[:id])
    @post.destroy
    redirect_to new_post_path
  end

    private
    def post_params
        params.require(:post).permit( :json, :description, :title, :data, :user_id )
    end
end

Here is my db schema:

ActiveRecord::Schema.define(version: 20161127203635) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "posts", force: :cascade do |t|
    t.text     "description"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.string   "title"
    t.integer  "user_id"
    t.string   "json"
    t.json     "data"
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "first_name"
    t.string   "last_name"
    t.string   "username"
    t.date     "birthday"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree

end

When I go to query the JSON that is in my database, I don't get anything in return.

I do: psql mydatabase

Then I tried: SELECT data->>'name' AS name FROM posts

But it doesn't return anything.

Here's a JSON file that should be stored in my DB in the :data column:

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    },
    "text": {
        "data": "Click Here",
        "size": 36,
        "style": "bold",
        "name": "text1",
        "hOffset": 250,
        "vOffset": 100,
        "alignment": "center",
        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    }
}}

So what am I doing wrong? I need to be able to query the JSON.

Upvotes: 4

Views: 1518

Answers (1)

Nathaniel Turner
Nathaniel Turner

Reputation: 91

Form your post params like this

def post_params
    params.require(:post).permit(:description, :title, :user_id, json: {}, data: {})
end

Upvotes: 1

Related Questions