I'm using active model serialiser.
I want to render both 'status' and 'data' in JSON format, e.g.
{"status":"success","data":[{"id":1,"content":xxx"}]}
I've been able to produce the 'data' using the following code in my rails controller:
#jobs = Job.all
render json: #jobs
How can I render both 'status' and 'data'? I've tried doing:
#jobs = Job.all
render :json => { :status => :success, :data => #jobs }
This doesn't recognize my JobSerializer, so renders JSON output, but not with the attributes and associations specified in my JobSerializer.
I've also tried:
#jobs = Job.all
render :json => { :status => :success, :data => ActiveModel::ArraySerializer.new(#jobs, each_serializer: JobSerializer) }
This appears to work, i.e. renders a JSON response with the right attributes speicified in my JobSerializer, but doesn't recognise or render the associations in my JobSerializer (i.e. a has_many association)
Is there an easy way to do this that I'm missing?
You can do something like:
render :json => {
status: "success",
data: ContentSerializer.new( contents ).attributes
}
Try this
#jobs = Job.all
render json: #jobs, status: 200
if above dosent work try this one
#jobs = Job.all
render json: #jobs, status: 200, serializer: JobSerializer
maybe you can try to render on this way:
#jobs = Job.all
render :json => { :status => :success, :data => #jobs.to_json }
UPDATE:
if you want to render and related objects, this should look like:
render :json => { :status => :success, :data => #jobs.to_json(:include => :users) }
here I assumed that the job model has users
Add attr_accessor to your model class
class Job < ApplicationRecord
attr_accessor :status
end
2.Then add same attribute to your serilizer
class JobSerializer < ActiveModel::Serializer
attributes :id, :name, :address, :email,:status
has_one :branch
end
3.Done add code like this in your controller
#job.status = 'success'
render json: #job, status: 200
#jobs = Job.all
render :json => { :status => :success, :data => (ActiveModel::ArraySerializer.new(#jobs, each_serializer: JobSerializer))
For has_many association to work, the association needs to be defined in both the model and serializer
class JobSerializer < ActiveModel::Serializer
has_many :association
end
class Section < ApplicationRecord
has_many :association
end
Related
I have two rails controller actions:
def show
#project = Project.find(params[:id])
render json: #project,
:only => [:id, :compilation_id],
:methods => :track_name,
:include => {
:user => { :only => [:id, :email] }
}
end
def list_users
render json: User.select(:id, :email)
end
I would like to render them both in one response. What is the best way to go about doing this? I tried using the to_json method as described here but I read that that method is deprecated and I also noticed that it escapes the content which seems to be unnecessary. Any help is appreciated.
For the cases where you need json structures complicated enough for to_json to look readable, I recommend to use active_model_serializers gem.
You can then define two serializer classes like this:
class ProjectSerializer < ActiveModel::Serializer
attributes :id, :compilation_id
has_many :users
end
class UserSerializer < ActiveModel::Serializer
attributes :id, :email
end
And then in your controller:
class ProjectsController < ApplicationController
def show
#project = Project.find(params[:id])
render json: #project, serializer: ProjectSerializer, status: 200
end
end
As a bonus track, you can even cache the response!
The solution, of course, was pretty simple:
project = Project.select(:id, :compilation_id, :user_id, :genre_id, :ordering).find(params[:id])
render json: { :project => project,
:users => User.select(:id, :email),
:genres => Genre.select(:id, :name),
:track_name => project.track_name
}
Please reference this question: same question or another similar question
I cannot seem to get my work scaffold to include the image URL from paperclip to JSON. I need this url to do some ajax manipulation to the dom.
To my understanding you add a def in a model and then you add a extra line to the format.json in the controller.
when I add the #work.avatar_url to my controller method def create it throws up a syntax error
syntax error, unexpected ',', expecting tASSOC
I'm really new to rails and MVC. All the answers make it sound so easy. Unfortunately, I'm just guessing and checking...
Controller Link: works_controller.rb
My Def Create
def create
#work = Work.new(params[:work])
respond_to do |format|
if #work.save
format.html { redirect_to #work, notice: 'Work was successfully created.' }
format.json { render json: #work, status: :created, location: #work }
else
format.html { render action: "new" }
format.json { render json: #work.errors, status: :unprocessable_entity }
end
end
end
Git Link Model: work.rb
class Work < ActiveRecord::Base
validates :name, :presence => true
has_many :categoryworks
has_many :categories, :through => :categoryworks
accepts_nested_attributes_for :categories
attr_accessible :name, :subtitle, :category_ids, :svg, :post_a, :post_b, :post_c, :post_d, :avatar
has_attached_file :avatar, :styles => { :medium => "1280x700>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
def avatar_url
avatar.url(:medium)
end
end
Try
format.json { render json: #work.as_json(:methods => [:avatar_url]), status: :created, location: #work }
instead of what you have used.
I am running into a strange situation, considering the following models:
class Collection < ActiveRecord::Base
attr_accessible :name, :season, :year
has_many :collection_items_assocs
has_many :items, :through => :collection_items_assocs
end
class Item < ActiveRecord::Base
attr_accessible :name, :reference, :item_type_id
has_many :pictures
has_one :item_type
end
class CollectionItemsAssoc < ActiveRecord::Base
attr_accessible :collection_id, :item_id
belongs_to :item
belongs_to :collection
end
I can successfully retrieve Items associated to a Collection with the following code:
# GET /collections/1
# GET /collections/1.json
def show
#collection = Collection.find(params[:id])
#collection.items = Collection.find(params[:id]).items
respond_to do |format|
format.json { render json: #collection.to_json(:include => {:items => #collection}) }
end
end
But when I try to include pagination (for items) like that
# GET /collections/1
# GET /collections/1.json
def show
#collection = Collection.find(params[:id])
**#collection.items = Collection.find(params[:id]).items.paginate(:page => params[:page],:per_page =>1)**
respond_to do |format|
format.json { render json: #collection.to_json(:include => {:items => #collection}) }
end
end
It works for the following call
/retailapp/collections/1?format=json&**page=1**
Then if I call
/retailapp/collections/1?format=json&**page=2**
the records in the association table CollectionItemsAssoc are deleted
I really don't get it
Thanks for your help
The problem is the code to fetch the items
#collection.items = Collection.find(params[:id]).items
it assigned the fetched items to current collection object.
you need to change the response to support the pagination on associate objects
def show
#collection = Collection.find(params[:id])
respond_to do |format|
format.json {
json_hash = #collection.as_json
json_hash[:items] = #collection.items.paginate(:page => params[:page],:per_page =>1).as_json
render json: json_hash.to_json
}
end
Additionally you can overwrite to_json method inside Collection model.
I have 3 objects: users, travels, points.
A user has many travels, a travel has many points, a point belongs to one travel e one user.
A travel has also a boolean attribute (:open) which tells if is it in curse or not.
The problem is that I can't save "travel_id" of the current travel in my points table.
Here is the code:
class Point < ActiveRecord::Base
belongs_to :travel, :foreign_key=> "travel_id"
belongs_to :user, :foreign_key=> "user_id"
end
class Travel < ActiveRecord::Base
has_one :user, :foreign_key => "user_id"
has_many :ways
has_many :points
attr_accessible :description, :start_date, :last_date
validates_date :last_date, :on_or_after => :start_date
end
Points controller:
...
def create
#point = Point.new(params[:point])
#point.user_id = current_user.id
#travel = current_user.travels.find(:all, :conditions => {:open => true})
#point.travel_id = #travel.id
respond_to do |format|
if #point.save
format.html { redirect_to(#point, :notice => 'Point was successfully created.') }
format.xml { render :xml => #point, :status => :created, :location => #point }
else
format.html { render :action => "new" }
format.xml { render :xml => #point.errors, :status => :unprocessable_entity }
end
end
end
...
Every time I try to save a new point, #point.travel_id = -614747648
A few things could do with being fixed up here.
Firstly, you don't need to specify :foreign_key when the key is just the same as the relation name + _id.
Second, you don't need to (and generally shouldn't) set the foo_id fields directly; it's more usual to do #point.user = current_user.
Thirdly, and the direct cause of your problem, is that #travel has been set to the result of a find(:all, ...) call - so it's an Array of Travel objects. What you're saving into #point.travel_id will be Ruby's internal id for the #travel Array, rather than a database ID for a single row.
I am having that problem that my model dont want to save. I have a token field input for tags.
I have followed this guide for the token input: http://railscasts.com/episodes/258-token-fields
I get this error when I try to create a new konkurrancer:
NoMethodError in Admin/konkurrancersController#create
undefined method `class_name' for nil:NilClass
Rails.root: C:/Rails/konkurranceportalen
Application Trace | Framework Trace | Full Trace
app/models/konkurrancer.rb:15:in `tag_tokens='
app/controllers/admin/konkurrancers_controller.rb:48:in `new'
app/controllers/admin/konkurrancers_controller.rb:48:in `create'
http://pastie.org/1834194
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"yo7wcAQl81tx3zZpPP44ENPYzYRZLpgyYKY+HK3yFKM=",
"konkurrancer"=>{"name"=>"Vind en rejse",
"banner2"=>"asdasd",
"tracking"=>"sadasd",
"vaerdi"=>"12222",
"tid"=>"1 min",
"tag_tokens"=>"1",
"bedom"=>"2",
"kategori_id"=>"9",
"form"=>"Nyhedsbrev",
"partner"=>"Iqmedier",
"udtraekkes(3i)"=>"30",
"udtraekkes(2i)"=>"4",
"udtraekkes(1i)"=>"2011",
"udtraekkes(4i)"=>"08",
"udtraekkes(5i)"=>"26",
"arrangeor"=>"",
"note"=>""},
"commit"=>"Opret konkurrence"}
My konkurrancer model:
class Konkurrancer < ActiveRecord::Base
attr_accessible :name, :tag_tokens
has_many :tagsmenus
has_many :tags, :through => :tagsmenus
attr_reader :tag_tokens
def tag_tokens=(ids)
self.tag_ids = ids.split(",")
end
end
My tag model:
class Tag < ActiveRecord::Base
has_many :tagsmenus
has_many :konkurrancers, :through => :tagsmenus
has_friendly_id :name, :use_slug => true
before_save :assign_cached_slug, :unless => :cached_slug?
protected
def assign_cached_slug
self.cached_slug = self.name.gsub(/\s+/, '_').gsub(/[^\w\-]/, '')
end
end
My tagmenu model:
class Tagsmenu < ActiveRecord::Base
end
My controller:
def new
#konkurrancer = Konkurrancer.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #konkurrancer }
end
end
# POST /konkurrancers
# POST /konkurrancers.xml
def create
#konkurrancer = Konkurrancer.new(params[:konkurrancer])
respond_to do |format|
if #konkurrancer.save
format.html { redirect_to(:admin_konkurrancers, :notice => 'Konkurrancer was successfully created.') }
format.xml { render :xml => :admin_konkurrancers, :status => :created, :location => #konkurrancer }
else
format.html { render :action => "new" }
format.xml { render :xml => #konkurrancer.errors, :status => :unprocessable_entity }
end
end
end
I have created the join table and the model and also added the relation to my tag model.
Your model has some conflicting statements. You first define:
attr_accessor ... :tag_tokens
then later have:
attr_reader :tag_tokens
which is not necessary given the first line or vice versa given that later you have a deinition for the setter:
def tag_tokens(ids)
self.tag_ids = ids.split(',')
end
I don't see tag_ids defined either given it is not a column in your table. You should probably remove the attr_accessor definition for the tag_tokens and then define the tag_ids method for starters.
class Tagsmenu < ActiveRecord::Base
belongs_to :konkurrancer
belongs_to :tag
end