Subnodes in a json template - ruby-on-rails

I have a template for json using the JB gem: index.json.jb
https://github.com/amatsuda/jb
It outputs all the settings with some attributes per record.
Settings also have a metadata field, which is a postgres jsonB field. I'd like to loop through the metadata fields contents and add it to my json template. I've tried all sorts of ways and I can't figure out how to do this.
json = {}
json[:settings] = #settings.map do |setting|
{
id: setting.id,
category: setting.category,
created_at: setting.created_at,
updated_at: setting.updated_at,
notes: setting.notes,
name: setting.full_name,
setting.metadata.map do |meta|
{
meta[0]: meta[1]
}
end
}
end

Related

Rails API: Cannot whitelist JSON field attribute

I'm building a rails API with a model containing an attribute data of JSON type. (PSQL)
But when I try to post something like this
{ model: { name: 'Hello', data: { a: 1, b: 2 } } }
Rails thinks a and b are the attributes of a nested data association... It considers then they are unpermitted params.
The thing is, { a: 1, b: 2 } is the value of my field data.
How to provide JSON value to an attribute ?
-
Edit:
The error displayed is:
Unpermitted parameters: name, provider, confidence, location_type, formatted_address, place_id, types, locality, ...
The value of the data attribute is { name: 'Name', provider: 'Provider', ... }
Like I said Rails thinks they are the attributes of a nested data association.
-
Log:
Pastebin
if the keys are unknown in advance this could be a workaround:
def model_params
data_keys = params[:model].try(:fetch, :data, {}).keys
params.require(:model).permit(data: data_keys)
end
Credit goes to aliibrahim, read the discussion https://github.com/rails/rails/issues/9454 (P.S seems like strong parameters will support this use case in Rails 5.1)
When you post something, you have to make sure that your json have the same parameters that your controller.
Example rails api:
def example
#model = Model.new(params)
#model.save
render(json: model.to_json, status: :ok)
end
def params
params.permit(:name, :provider, {:data => [:a, :b]})
end
Example front-end json for post:
var body = {
name: 'myName',
provider: 'provider',
data: {
a: 'something',
b: 'otherthing',
}
};
For some reason rails doesnt recognize a nested json, so you need to write into params.permit that data will be a json with that syntax, if where a array, the [] should be empty.

How to save metadata into database from a rake file (rails)?

I am building a script to scrape data from a website. You can see the full code here: Undefined method 'click' for nil:NilClass (Mechanize)
Anyways, I have trouble to save this metadata into the database:
members = member_links.map do |link|
member = link.click
name = member.search('title').text.split('|')[0]
institution = member.search('td~ td+ td').text.split(':')[0]
dob = member.search('.birthdate').text.strip[1..4]
{
name: name.strip,
institution: institution.strip,
dob: dob,
bio: bio
}
end
Thus, how can I accomplish this?
Well, it should be as simple as:
Datum.create!(
name: name.strip,
institution: institution.strip,
dob: dob,
bio: bio
)
This is very basic Rails knowledge, make sure you've read Active Record Basics guide.

How to get user object with belongs_to in ember js?

I have two models Recipe and User. I can't get the user object in recipe. What am I doing wrong?
App.Recipe.find(1).get('title') // Returns "recipe01 title". All works fine.
App.Recipe.find(1).get('user') // Returns null
user.js.coffee
App.User = DS.Model.extend
email: DS.attr('string')
recipes: DS.hasMany('App.Recipe')
recipe.js.coffee
App.Recipe = DS.Model.extend
user: DS.belongsTo('App.User')
title: DS.attr('string')
my json array
{
recipe: {
id: 1,
title: "recipe01",
user: {
id: 1,
name: "ejiqpep",
email: "ejiqpep#gmail.com",
}
}
}
By default Ember Data expects dependent records to be referenced by key. Then you can either sideload the extra records or let Ember lazy load them from their API endpoint.
{
recipe: {
id: 1,
title: "recipe01",
user_id: 1
},
user: {
id: 1,
name: "ejiqpep",
email: "ejiqpep#gmail.com"
}
}
However, you can also instruct the Adapter that the records are embedded.
There are two types of embedded record loading embedded: 'always', where Ember will both receive and send any changes with the objects embedded.
App.Adapter.map 'App.Recipe',
user:
embedded: 'always'
Or embedded:'load' where Ember will load embedded objects from JSON but will save changes back to the API as separate objects.
App.Adapter.map 'App.Recipe',
user:
embedded: 'load'
Which of the three options you'd like to take is up to you.
Embedded objects have only recently been implemented and there are a couple of issues around them (see the Ember-Data issues on Github), but will work without any changes to your existing server.

Create multiple documents with array

I have the following array:
#unregistered_users = ['my#email.com', 'your#email.com', ...]
Now, I want to create a document for each array element:
#unregistered_users.each do |email_address|
Model.create(email: email_address, user: self.user, detail: self)
end
But it only creates a single document (the first element of the array). The other array elements are simply not created. Why?
We're using Ruby 1.9.3-p385, Rails 3.2.12, MongoID 3.0.0 and MongoDB 2.2.3
Update #1
So, we had a custom _id field with a custom random token using SecureRandom.hex(64).to_i(16).to_s(36)[0..127].
After I removed it worked normally, but with regular mongo ID's (which is not what we want).
Update #2
This is how the token are being generated:
class Model
include Mongoid::Document
include Mongoid::Timestamps
...
field :_id, default: SecureRandom.hex(64).to_i(16).to_s(36)[0..127]
...
index( { _id: 1 }, { unique: true } )
end
Try something like this to check what are the errors on the mongoid model:
#unregistered_users.each do |email_address|
model = Model.create(email: email_address, user: self.user, detail: self)
puts model.errors.inspect unless model.persisted?
end
or use create! to raise an exception and see what's happening

Modify data structure of CarrierWave image uploader

I'm using the ruby gem CarrierWave to handle images on my rails app, which is a mobile backend API. Is there a way to store the image url and thumb url directly on the parent object?
This is the default behavior, shown in the post object's json. Notice the nested JSON:
{
created_at: "2012-11-17T18:24:04Z",
description: "this is the content",
id: 6,
user_id: 1,
picture: {
url: "/uploads/entry/picture/6/wtf_llama.jpeg",
thumb: {
url: "/uploads/entry/picture/6/thumb_wtf_llama.jpeg"
}
},
updated_at: "2012-11-26T08:16:43Z"
}
What I'd like to see:
{
created_at: "2012-11-17T18:24:04Z",
description: "this is the content",
id: 6,
user_id: 1,
picture_url = "/uploads/entry/picture/6/wtf_llama.jpeg",
thumb_url = "/uploads/entry/picture/6/thumb_wtf_llama.jpeg"
updated_at: "2012-11-26T08:16:43Z"
}
Is this possible?
Why storing those paths in models? Improve response (view or controller), not persistence layer (model). I believe it's easiest to achieve with as_json. Either add picture_url methods to model or merge additional entries to your final hash.

Resources