Using activerecord-postgis-adapter, how can I parse / encode wkt in results from database query?
I've got a simple model of Places:
class CreatePlaces < ActiveRecord::Migration[5.1]
def change
create_table :places do |t|
t.string :name
t.st_point :coords, :geographic => true
t.timestamps
end
change_table :places do |t|
t.index :coords, using: :gist
end
end
end
I get all places in following way:
class PlacesController < ApplicationController
def index
#places = Place.all
render json: #places.to_json
end
end
But my JSON in response contains WKT:
[
{
"id": 1,
"name": "test name 1",
"coords": "POINT (50.324192 19.037805)",
"created_at": "2017-09-07T20:29:19.203Z",
"updated_at": "2017-09-07T20:29:19.203Z"
}
]
I can map #places and encode coords like this:
class PlacesController < ApplicationController
def index
#places = Place.all
#places.map { |k,v| k.coords = RGeo::GeoJSON.encode(k.coords, json_parser: :json) }
render json: #places.to_json
end
end
And then I get what I wanted - encoded/parsed coords in GeoJSON form:
[
{
"id": 1,
"name": "test name 1",
"coords": {
"type": "Point",
"coordinates": [
50.324192,
19.037805
]
},
"created_at": "2017-09-07T20:29:19.203Z",
"updated_at": "2017-09-07T20:29:19.203Z"
}
]
Is it right way to encode POINT?
Add this code to one of your initializers:
RGeo::ActiveRecord::GeometryMixin.set_json_generator(:geojson)
See https://stackoverflow.com/a/6221804
Related
I am working on a commenting system, where the comments and replies are on the same table, with replies having a reply_to column set to the id of the parent comment
class CreateComments < ActiveRecord::Migration[7.0]
def change
create_table :comments do |t|
t.text :content
t.references :user, null: false, foreign_key: true
t.bigint :reply_to
t.integer :upvote_count
t.timestamps
end
end
end
In my comments_controller I have the following action and a helper function respectively to aid with querying the comments and replies inclusive of the user that created them.
class Api::CommentsController < ApplicationController
before_action :authenticate_user!, only: [:create, :destroy]
def index
#comments = Comment.where(reply_to: nil).includes(:user).order(created_at: :desc)
#comments = #comments.map do |comment|
comment.as_json.merge(replies: get_replies(comment.id))
end
render json: #comments, include: :user, status: :ok
end
private
# get all replies for a comment
def get_replies(comment_id)
Comment.where(reply_to: comment_id).includes(:user).order(created_at: :desc)
end
end
With this query, I am only getting the user included in the replies but not the parent comment as shown below
[
{
"id": 1,
"content": "hey this is a comment 1",
"user_id": 2,
"reply_to": null,
"upvote_count": null,
"created_at": "2022-09-06T19:00:38.996Z",
"updated_at": "2022-09-06T19:00:38.996Z",
"replies": [
{
"id": 3,
"content": "hey this is a reply to comment 1",
"user_id": 1,
"reply_to": 1,
"upvote_count": null,
"created_at": "2022-09-06T19:07:53.729Z",
"updated_at": "2022-09-06T19:07:53.729Z",
"user": {
"id": 1,
"provider": "email",
"uid": "madmax#user.name",
"allow_password_change": false,
"avatar": "0",
"email": "madmax#user.name",
"created_at": "2022-09-06T18:18:02.558Z",
"updated_at": "2022-09-07T21:53:13.804Z"
}
}
]
},
{
"id": 2,
"content": "hey this is a comment comment 2",
"user_id": 2,
"reply_to": null,
"upvote_count": null,
"created_at": "2022-09-06T19:04:14.433Z",
"updated_at": "2022-09-06T19:04:14.433Z",
"replies": []
}
]
My goal is to have the user included in both the parent comment and also the replies
I want this form
"data": [
{
"id": 2,
"searchable_type": "User",
"email": "abc",
"first_name": "abc",
"last_name": "xyz",
"created_at": "2022-08-05T09:40:18.986Z",
"updated_at": "2022-08-05T09:40:18.986Z"
},
{
"id": 3,
"searchable_type": "blog",
"tittle": "user",
"created_at": "2022-08-05T09:40:18.986Z",
"updated_at": "2022-08-05T09:40:18.986Z"
}
]
I want to return whole object for each model respectively by using Pg Search multi search it just return a content ,searchable_type and searchable_id as attached images belowIt is my postman image for blog returnIt is my postman image for user return
[My search controller, User and blog models]
class Api::V1::SearchController < Api::V1::ApiController
def index
#query = params[:value]
#results = PgSearch.multisearch(#query)
render json: { data: #results}, status: :ok
end
end
class Blog < ApplicationRecord
include PgSearch::Model
multisearchable against: [:id, :title, :created_at, :updated_at ]
end
class User < ApplicationRecord
include PgSearch::Model
multisearchable against: [:id, :email, :first_name, :last_name ]
end
Change
#results = PgSearch.multisearch(#query)
to
#results = PgSearch.multisearch(#query).includes(:searchable).map(&:searchable)
I'm working on an API based Rails application, I don't know how to show all associated items in one request like my models
todo.rb
class Todo < ApplicationRecord
has_many :items, dependent: :destroy
validates_presence_of :title, :created_by
end
item.rb
class Item < ApplicationRecord
belongs_to :todo
validates_presence_of :name
end
in the controller
def show
json_response(#todo)
end
private
def set_todo
#todo = Todo.find(params[:id])
end
The endpoit for single todo
https://example.com/todos/1
and it showing like this
{
"id": 1,
"title": "Hello World!",
"created_by": "2",
"created_at": "2018-04-26T11:19:31.433Z",
"updated_at": "2018-04-26T11:19:31.433Z"
}
My question is how do I show all items which created by this todo in same end point request.
Try using ActiveModel::Serializers::JSON#as_json
For e.g.
def show
render json: #user.as_json(include: :posts), status: 200
end
That should return a response like
{
"id": 1,
"name": "Konata Izumi",
"age": 16,
"created_at": "2006/08/01",
"awesome": true,
"posts": [
{
"id": 1,
"author_id": 1,
"title": "Welcome to the weblog"
},
{
"id": 2,
"author_id": 1,
"title": "So I was thinking"
}
]
}
def show
render json: {"todos" => {"todo" => #todo, "items" => #todo.items }}, status:200
end
Alternatively you can use serializers for more filters and modifications of response datas
I am using AMS version 0.10 and looking to use the json-api specification for rendering my responses. However, I am having difficultly rendering the 'included' key for my relationship data. I have the following setup:
products_controller.rb
class Api::V1::ProductsController < ApplicationController
...
respond_to :json
def show
respond_with Product.find(params[:id])
end
...
product_serializer.rb
class ProductSerializer < ActiveModel::Serializer
attributes :id, :title, :price, :published
has_one :user
end
user_serializer.rb
class UserSerializer < ActiveModel::Serializer
attributes :id, :email, :auth_token, :created_at, :updated_at
end
products_controller_spec.rb
before(:each) do
#product = FactoryGirl.create :product
get :show, params: { id: #product.id }
end
...
it "has the user as a embeded object" do
product_response = json_response
puts "&&&&&&&&&&&&&&&"
puts product_response #output below
#expect(product_response[:user][:email]).to eql #product.user.email
end
...
json_response
{:data=>{:id=>"1", :type=>"products", :attributes=>{..working..}, :relationships=>{:user=>{:data=>{:id=>"1", :type=>"users"}}}}}
I would like to know how to get the 'included' section for the nested resource.
Example (from http://jsonapi.org/format/#introduction)
{
"data": [{
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"links": {
"self": "http://example.com/articles/1"
},
"relationships": {
"author": {
"links": {
"self": "http://example.com/articles/1/relationships/author",
"related": "http://example.com/articles/1/author"
},
"data": { "type": "people", "id": "9" }
}
}],
"included": [{
"type": "people",
"id": "9",
"attributes": {
"first-name": "Dan",
"last-name": "Gebhardt",
"twitter": "dgeb"
},
"links": {
"self": "http://example.com/people/9"
}
},
I have never used AMS before so any help will be greatly appreciated.
Many thanks
Just for anyone else the solution is here https://github.com/rails-api/active_model_serializers/blob/master/docs/jsonapi/schema.md.
Essentially i add the following to my controller action (GET products/1)
render json: product, include: params[:include]
This will allow the requesting system to determine whether they would like to include the nested models by adding the parameter include='user' for the api to process.
Thanks
I am trying to use custom serializers for the relationships in a serializer and the json_api adapter enabled. However the relationships are not serialized correctly (or, better, not at all displayed/serialized).
PostController.rb
def index
render json: Post.all, each_serializer: Serializers::PostSerializer
end
Serializer
module Api
module V1
module Serializers
class PostSerializer < ActiveModel::Serializer
attributes :title, :id
belongs_to :author, serializer: UserSerializer
has_many :post_sections, serializer: PostSectionSerializer
end
end
end
end
JSON output:
{
"data": [
{
"attributes": {
"title": "Test Title"
},
"id": "1",
"relationships": {
"author": {
"data": {
"id": "1",
"type": "users"
}
},
"post_sections": {
"data": [
{
"id": "1",
"type": "post_sections"
}
]
}
},
"type": "posts"
}
]
}
As you can see, the relationships are not fulfilled, which happens only if I specify a custom serializer for the relationships!!
If I do something like this:
module Api
module V1
module Serializers
class PostSerializer < ActiveModel::Serializer
attributes :title, :id
belongs_to :author # no custom serializer!
has_many :post_sections # no custom serializer!
end
end
end
end
The relationships are shown correctly, but not using a custom serializer...
What's the issue here ?
EDIT
According to the json API 1.0 Format, what I am getting back is the so-called resource identifier object.
The following primary data is a single resource identifier object that
references the same resource:
{ "data": {
"type": "articles",
"id": "1" } }
Is there a way to prevent getting resource identifier objects, and get the actual data instead ?
Relationships only returns id and type according to json-api exmaples. If you need to return more information about this relation you should add include option on your render action.
Ex.
PostController.rb
class PostsController < ApplicationController
def show
render json: #post, include: 'comments'
end
end
Serializers
class PostSerializer < ActiveModel::Serializer
attributes :id, :title, :content
has_many :comment, serializer: CommentSerializer
end
class CommentSerializer < ActiveModel::Serializer
attributes :id, :title, :content
end
JSON output:
{
"data": {
"id": "1",
"type": "post",
"attributes": {
"title": "bla",
"content": "bla"
},
"relationships": {
"comment": {
"data": [
{
"type": "comments",
"id": "1"
}
]
}
}
},
"included": {
{
"id": "1",
"type": "comments",
"attributes": {
"title": "test",
"content": "test"
}
}
]
}
Just to add to #Bruno Bacarini's answer, you may also include chained associations by using:
render #posts, include: ['authors.profile', 'comments']
source: joaomdmoura's comment on github