I try to build json with geojson datas.
In my controller :
def index
....
respond_to do |format|
format.html
format.json { render json: { type: 'FeatureCollection', features: pois_geojson + tracks_geojson} }
end
and for show
def show
...
respond_to do |format|
format.html
format.json { render json: { type: 'FeatureCollection', features: poi_geojson + track_geojson} }
end
For index, all work fine and my json is good. I call this method for build json.
Methods for show
def poi_geojson
{
type: 'Feature',
RGeo::GeoJSON.encode(#poi.lonlat),
properties: {
name: #poi.name,
:'marker-color' => '#00607d',
:'marker-symbol' => 'circle',
:'marker-size' => 'medium'
}
}
end
def track_geojson
{
type: 'Feature',
geometry: RGeo::GeoJSON.encode(#track.path),
properties: {
:'color' => '#ff7800',
:'weight' => '5',
:'opacity' => '0.65'
}
}
end
Methods for index
def pois_geojson
#pois.map do |poi|
{
type: 'Feature',
RGeo::GeoJSON.encode(poi.lonlat)
properties: {
name: poi.name,
:'marker-color' => '#00607d',
:'marker-symbol' => 'circle',
:'marker-size' => 'medium'
}
}
end
end
def tracks_geojson
#tracks.map do |track|
{
type: 'Feature',
geometry: RGeo::GeoJSON.encode(track.path),
properties: {
:'color' => '#ff7800',
:'weight' => '5',
:'opacity' => '0.65'
}
}
end
end
As you can see, the methods are similars, but I don't understand why for index it work fine, and not for the show.
I have this error :
`undefined method '+' for #`
for this line :
`format.json { render json: { type: 'FeatureCollection', features: poi_geojson + track_geojson} }`
There is no + method for hash instances, to form an array from two hashes you can do the following:
[pois_geojson, tracks_geojson]
The reason why this works for pois_geojson and tracks_geojson is because both of them are already arrays.
Related
This is what I have:
def index
#attachments = current_user.attachments.all
respond_to do |format|
format.json do
render :json => #attachments.map { |o| { url: o.picture.thumb.url }}
end
end
end
=> [{:url=>"/uploads/attachment/picture/7/thumb_df3c0c3c.jpg"}, {:url=>"/uploads/attachment/picture/12/thumb_dd7839ee.jpg"}, ... }]
How can I change the key from :url to :thumb?
=> [{:thumb=>"/uploads/attachment/picture/7/thumb_df3c0c3c.jpg"},
{:thumb=>"/uploads/attachment/picture/12/thumb_dd7839ee.jpg"}, ... }]
This is the whole object after: render :json => #attachments
My goal: thumb: thumb: "/uploads/attach..."
Background: https://www.froala.com/wysiwyg-editor/docs/concepts/image-manager
I use the gem carrierwave to create a thumb
response.map! { |urls| { :thumb => urls[:url] } }
change key from "url" to "thumb"
render :json => #attachments.map { |o| { **thumb: o.picture.thumb.url** }}
So I have been playing around with acts_as_taggable_on in active admin, and for the most part everything is working as expected.
However, whenever I search for tags, and add an existing tag to a model, it seems to save it as the ID, rather than as the name. Creation of new tags returns the name fine, and when I go to edit the object again the tags remain tagged by the name. But when I try and add another tag, one that already exists in the database, it returns the name in the form, and seems to save OK, but when I go back to edit the onject again the tag shows up as an ID, rather than the name.
In admin/gift.rb:
controller do
def autocomplete_gift_tags
#tags = ActsAsTaggableOn::Tag
.where("name LIKE ?", "#{params[:q]}%")
.order(:name)
respond_to do |format|
format.json { render json: #tags , only: [:id, :name], root: false }
end
end
end
In tag-autocomlete.js:
$(document).ready(function() {
$('.tagselect').each(function() {
var placeholder = $(this).data('placeholder');
var url = $(this).data('url');
var saved = $(this).data('saved');
$(this).select2({
tags: true,
placeholder: placeholder,
minimumInputLength: 1,
initSelection: function(element, callback) {
saved && callback(saved);
},
ajax: {
url: url,
dataType: 'json',
data: function(term) {
return {
q: term
};
},
results: function(data) {
return {
results: data
};
}
},
createSearchChoice: function(term, data) {
if ($(data).filter(function() {
return this.name.localeCompare(term) === 0;
}).length === 0) {
return {
id: term,
name: term
};
}
},
formatResult: function(item, page) {
return item.name;
},
formatSelection: function(item, page) {
return item.name;
}
});
});
});
And in my _gift_form.html.erb:
<%= f.input :tag_list, label: "Tags", input_html: { data: { placeholder: "Enter tags", saved: f.object.tags.map{|t| {id: t.name, name: t.name}}.to_json, url: autocomplete_gift_tags_path }, class: 'tagselect' } %>
Can't work out why the new ones are working, but the existing tags are not.
change this:
respond_to do |format|
format.json { render json: #tags , only: [:id, :name], root: false }
end
to this:
respond_to do |format|
format.json { render :json => #tags.collect{|t| {:id => t.name, :name => t.name }}}
end
Ember-data seems to want an array of data for a hypothetical Color model to look like:
{
"colors": [{
name: "red"
}, {
name: "blue"
}, {
name: "green"
}]
}
i.e. It wants a root element that is the plural of whatever type your model is. I am wondering how to get rails to send JSON that way using the active_model_serializers gem. Here is what I have:
# GET /colors
# GET /colors.json
def index
#colors = Color.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #colors, :root => 'colors' }
end
end
but this produces:
{
colors: [
{
colors: {
name: "red"
}
}, {
colors: {
name: "blue"
}
}, {
colors: {
name: "green"
}
}
}]
}
i.e. There is a root element on the array and each object. I want it just on the array. Any help is appreciated. Thanks!
I eventually solved this by adding my own custom serializer
app/serializers/color_serializer.rb
class ColorSerializer < ActiveModel::Serializer
attributes :name
self.root = false
end
and then used
render json: #colors, each_serializer: ColorSerializer
which disabled the per-object root element while preserving the root element on the array.
I've got the following model
Ext.regModel("Entries", {
fields: [
{name: "id", type: "int"},
{name: "title", type: "string"},
{name: "bought", type: "boolean"},
],
proxy: {
type: 'rest',
url: '/lists',
format: 'json',
reader: {
type: 'json'
}
}
});
Then I've got a list, which is populated from this model
...
store: new Ext.data.Store({
model: "Entries",
autoLoad: true,
remoteFilter: true
}),
...
The list is populated correctly. But when I try to perform the following
listeners: {
itemswipe: function (record, index, item, e) {
var el = Ext.get(item);
el.toggleCls("crossedOut");
var store = record.getStore();
var rec = store.getAt(index);
if (el.hasCls('crossedOut')) {
rec.set('bought', true);
rec.save({
success: function() {
console.log("Saved!");
}
});
} else {
console.log('not crossed out');
rec.set('bought', false);
rec.save({
success: function() {
console.log("Saved!");
}
});
}
}
}
when swipe event is fired, I've got the following error
Uncaught TypeError: Cannot read property 'data' of undefined gsencha-touch.js:6
(anonymous function) sencha-touch.js:6
Ext.data.Connection.Ext.extend.onCompletesencha-touch.js:6
Ext.data.Connection.Ext.extend.onStateChangesencha-touch.js:6
(anonymous function)
I understand, that there is some problem with the payload I return, but I can't find an example of the correct one, and all my guesses do not work.
In backend I return the following
format.json {render :json => {:data => #list, :success=> true, :id => #list.id}}
I'm using the ExtJS 4 preview, but it should work the same with Sencha Touch. Your problem might be related to the nesting of the returned json. Here's what works for me.
In the Rails controller:
def index
respond_with #entries = Entry.all do |format|
format.json { render :json => {:success => true, :data => #entries, :total => #entries.count} }
end
end
def show
respond_with #entry = Entry.find(params[:id]) do |format|
format.json { render :json => {:success => true, :data => [#entry]} }
end
end
def create
respond_with #entry = Entry.create(params[:records][0]) do |format|
format.json { render :json => {:success => true, :data => [#entry]} }
end
end
def update
#entry = Entry.find(params[:id])
#entry.update_attributes(params[:records][0])
respond_with #entry do |format|
format.json { render :json => {:success => true, :data => [#entry]} }
end
end
ExtJS model:
Ext.regModel("Entries", {
fields: [
{name: "id", type: "int"},
{name: "title", type: "string"},
{name: "bought", type: "boolean"},
],
proxy: {
type: 'rest',
url: '/lists',
format: 'json',
reader: {
type: 'json',
root: 'data',
record: 'entry'
}
}
});
Two differences with what you've done:
1/ The record option of the reader tells ExtJS to look for nested records in the json. It tells it to look for:
data: [
{
entry: {
id: 1,
title: "Title 1",
bought: true
}
}
]
instead of:
data: [
{
id: 1,
title: "Title 1",
bought: true
}
]
An alternative to setting the record property on the reader would be to disable nested json in Rails, by dumping this into your application config:
config.active_record.include_root_in_json = true
2/ When returning a single record, the json output should be the same as a collection, except you only have one record.
The Sencha Touch and ExtJS 4 docs can be a bit sparse sometimes, I found dissecting the examples is the best way to learn.
HTH
I ran into a similar problem when submitting a single record instead of a store. Setting a writer object with the name of your record as rootProperty solves the issue.
writer: {
type : 'json',
rootProperty : 'your_record'
}
want to get all db entries by a specific hash and return it as json. I use the following code:
#tasks = Task.find_all_by_hash(params[:hash])
respond_to do |format|
format.json { render :json => #tasks }
end
now i have the problem that my json file isn't correct. it has the following output:
[
{
task: {
hash: "9dfca619f00f5488785f6b74ad1b590beefaee7a88c04884bf197e7679f3"
id: 4
created_at: "2010-12-16T09:09:51Z"
updated_at: "2010-12-16T09:14:10Z"
done: true
name: "Hallo"
}
},
{
task: {
hash: "9dfca619f00f5488785f6b74ad1b590beefaee7a88c04884bf197e7679f3"
id: 5
created_at: "2010-12-16T09:12:37Z"
updated_at: "2010-12-16T09:12:37Z"
done: true
name: "Test"
}
},
...
]
but actually i want it like this:
{ tasks: [
{"id":"1","date_added":"0001-02-22 00:00:00","post_content":"Check out my content, this is loaded via ajax and parsed with JSON","author":"Ryan Coughlin"},
{"id":"2","date_added":"0000-00-00 00:00:00","post_content":"More content, loaded. Lets try to add a form in and post via ajax and append the new data","author":"Billy Bob"}
]}
any advice? thank you!
Try collecting the task alone to an array and create a json object using that. Some thing like
#tasks = Task.find_all_by_hash(params[:hash])
a = []
#tasks.each do |t|
a << t[:task]
end
b = {:tasks => a}
respond_to do |format|
format.json { render :json => b }
end