How to make routes for this URL? - ruby-on-rails

GET /bids?countries=us,uk&categories=finance,sports&channels=ca,ga
And the expected response is:
{
"bids": [
{ 'country': 'us', 'category': 'finance', 'channel': 'ca', 'amount': 4.0 },
{ 'country': 'us', 'category': 'finance', 'channel': '2ga', 'amount': 2.0 },
{ 'country': 'us', 'category': 'sports', 'channel': 'ca', 'amount': 2.0 },
{ 'country': 'us', 'category': 'sports', 'channel': 'ga', 'amount': 2.0 },
{ 'country': 'uk', 'category': 'finance', 'channel': 'ca', 'amount': 1.0 },
{ 'country': 'uk', 'category': 'finance', 'channel': 'ga', 'amount': 1.0 },
{ 'country': 'uk', 'category': 'sports', 'channel': 'ca', 'amount': 3.0 },
{ 'country': 'uk', 'category': 'sports', 'channel': 'ga', 'amount': 3.0 }
]
}
How to make routes for this url please help me out - any more experienced people know what I am doing for making routes ?. thanks in advance.

That's just a plain old index route with some extra query string parameters to filter the resource. You don't actually need to do anything special.
resources :bids, only: [:index]
class BidsController < ApplicationController
# GET /bids
# GET /bids?countries=us,uk&categories=finance,sports&channels=ca,ga
def index
#bids = Bid.all
# #todo implement filters
end
end
When matching a request URI with a route Rails will typically ignore the query string parameters unless they correspond to named placeholders in a defined route - GET /bids?id=1 for example will match GET /bids/:id.
Query string parameters are available in the params object. Just like parameters extraced from placeholders in the URI and are parsed identically to formdata in the body.

Related

Flutter map.addAll() results in failure

I got the following List<Map> in Flutter:
List<Map<String, dynamic>> recipeList = [
{
'name': 'rec1',
'id': 1,
'img': 'images/recipe.jpg',
'ingredients': [{
'name': 'salt',
'amount': '1',
'unit': '1',
},
{
'name': 'flour',
'amount': '100',
'unit': 'g',
},
{
'name': 'water',
'amount': '100',
'unit': 'g',
},
{
'name': 'milk',
'amount': '100',
'unit': 'g',
},],
},]
I pass it down through several Widgets and at some point I want to add the key value pair {'didBuy':false} to every Map inside the ingredients list (which is basically recipeList['ingredients']).
Thus I call:
List<Map<String, dynamic>> resultList = recipeList['ingredients'].map((elem) {
elem.addAll({'didBuy': false});
print(elem);
}).toList();
Unfortunately the following error message results: Dart Error: Unhandled exception:type '_InternalLinkedHashMap<String, bool>' is not a subtype of type 'Map<String, String>' of 'other'.
Does anybody know what is the correct way to add something to a map, without getting this error message?
Edited the question to be more precise.
EDIT2:
After calling the type of the List explicitly inside the Map as Hadrien suggested, I can add the key value pair with the boolean. Long term I want to fetch the data from the Internet, so I defined a RecipeObj:
class RecipeObj{
String name;
int id;
String img;
List<Map<String, dynamic>> ingredients;
RecipeObj(this.name, this.id, this.img, this.ingredients);
}
Here I explicitly state the type of the ingredients attribute, so I thought I could get of the explicit calling inside the (main) recipeList. But after passing the ingredients attribute down through some widgets, flutter recognizes it as List<Map<String, String>>, although I define it everywhere as an List<Map<String, dynamic>>, why is that?
dart infer the type of your ingredients list with Map<String, String>
you can specify the type by yourself inside your list
'ingredients': <Map<String, dynamic>>[ {
'name': 'salt',
'amount': '1',
'unit': '1',
},
or build a new Map<String, dynamic> inside your map function
List<Map<String, dynamic>> resultList = recipeList['ingredients'].map((elem) {
final map = Map<String, dynamic>.from(elem);
map.addAll({'didBuy': false});
return map;
}).toList();
This should do
List<Map<String,dynamic>> recipeList = [
at least if recipeList and ingredients point at the same collection instance.
var ingredients = recipeList;
Is this what you need?
void main() {
List<Map> recipeList = [
{
'name': 'rec1',
'id': 1,
'img': 'images/recipe.jpg',
'ingredients': [{
'name': 'salt',
'amount': '1',
'unit': '1',
},
{
'name': 'flour',
'amount': '100',
'unit': 'g',
},
{
'name': 'water',
'amount': '100',
'unit': 'g',
},
{
'name': 'milk',
'amount': '100',
'unit': 'g',
},]
},];
print("[DATA BEFORE ANY CHANGE]");
print("recipeList.length=${recipeList.length}");
print("recipeList[0][\"ingredients\"]=${recipeList[0]["ingredients"]}");
print("recipeList[0][\"ingredients\"].last=${recipeList[0]["ingredients"].last}");
print("recipeList[0][\"ingredients\"].length=${recipeList[0]["ingredients"].length}");
// no recipe is worth if it doesn't contain chocolate
recipeList[0]["ingredients"].add({
'name': 'cocoa powder',
'amount': '200',
'unit': 'g',
});
print("\n\n[DATA AFTER ADD]");
print("recipeList[0][\"ingredients\"].last=${recipeList[0]["ingredients"].last}");
print("recipeList[0][\"ingredients\"].length=${recipeList[0]["ingredients"].length}");
}
OUTPUT
[DATA BEFORE ANY CHANGE]
recipeList.length=1
recipeList[0]["ingredients"]=[{name: salt, amount: 1, unit: 1}, {name: flour, amount: 100, unit: g}, {name: water, amount: 100, unit: g}, {name: milk, amount: 100, unit: g}]
recipeList[0]["ingredients"].last={name: milk, amount: 100, unit: g}
recipeList[0]["ingredients"].length=4
[DATA AFTER ADD]
recipeList[0]["ingredients"].last={name: cocoa powder, amount: 200, unit: g}
recipeList[0]["ingredients"].length=5

Checking if variable exists in Rails 5 GET request

Not sure exactly how to ask this as I am learning as I go. I am creating/updating user information from my app to a third party CRM system.
I have two methods that run successfully with an after_save callback. During testing, I would comment one out so I can test the other but now I need to combine them with an if else statement.
What should happen when combined together is when User is saved, the system will see if a user exists on the CRM system - if agile_id?. If user exists, it will skip down to the update call and send over any updated contact data, but if it doesn't, it will create a new CRM contact record.
The error I am receiving in the browser is:
undefined method `agile_id?' for #<User:0x007ffe24cef318>
user.rb
...
after_save :sync_to_agilecrm
...
def sync_to_agilecrm
agile_id = AgileCRM.request :get, 'contacts/search/email/'+email, nil
if agile_id?
contact_data = {
'properties': [
{ 'type': 'SYSTEM', 'name': 'first_name', 'value': first_name },
{ 'type': 'SYSTEM', 'name': 'last_name', 'value': last_name },
{ 'type': 'SYSTEM', 'name': 'email', 'subtype': 'work', 'value': email },
{ 'type': 'SYSTEM', 'name': 'address', 'value': '{\"address\":\"225 George Street\",\"city\":\"NSW\",\"state\":\"Sydney\",\"zip\":\"2000\",\"country\":\"Australia\"}' },
]
}
parsed_contact_data = JSON.parse(contact_data.to_json)
print(AgileCRM.request :post, 'contacts', parsed_contact_data)
else
update_contact_data = {
'id': agile_id,
'properties': [
{ 'type': 'SYSTEM', 'name': 'first_name', 'value': first_name },
{ 'type': 'SYSTEM', 'name': 'last_name', 'value': last_name },
{ 'type': 'SYSTEM', 'name': 'email', 'subtype': 'work', 'value': email },
{ 'type': 'SYSTEM', 'name': 'address', 'subtype': 'work', 'value': address_line1 },
]
}
parsed_update_contact_data = JSON.parse(update_contact_data.to_json)
print(AgileCRM.request :put, 'contacts/edit-properties', parsed_update_contact_data)
end
end
...
agile_id and agile_id? aren't the same thing. You'll sometimes see ActiveRecord objects which have record.attribute? which is enabled through some meta programming.
So, when defining a variable such as agile_id, adding a question mark on the end won't just work, nor is it needed. a simple if agile_id should be sufficient.

How to print a JSON-structure from User models hierarchy

I am building an Rails 5 app and in this app I got a User model. Each user can have exactly one manager (using the attribute manager_id).
I want to print a JSON-structure (using Rabl) that shows how the User models are related. Meaning I want to print out how is manager to each user.
User 1 (manager_id is null)
|
User 2 (manager_id is 1)
User 3 (manager_id is 1)
|
User 4 (manager_id is 3)
This is what I want the UI to look like (this is already working I just need the JSON-structure to support it).
These is how the finished structure must look like.
datasource =
'name': 'Peter Fettingview'
'title': 'CEO'
'children': [
{
'name': 'Mike Palmer'
'title': 'CIO'
}
{
'name': 'Maria Persson'
'title': 'CTO'
'children': [
{
'name': 'James Hatton'
'title': 'Customer success'
}
{
'name': 'Lars Andersson'
'title': 'Customer success'
}
]
}
{
'name': 'Jan Roslund'
'title': 'Economy'
}
{
'name': 'Annika Holm'
'title': 'Sales'
}
]
This is what I got right now
attributes :id, :fullname
node :children do |n|
n.children.map { |c| partial("admin/users/index", :object => c) }
end
This is the output
[{
"id": 1,
"fullname": "Peter Fettingview",
"children": [{
"id": 2,
"fullname": "Richard Pooler"
},
{
"id": 1,
"fullname": "Mike Palmer"
}
]
},
{
"id": 2,
"fullname": "Richard Pooler",
"children": [{
"id": 3,
"fullname": "Mike Palmer"
}]
},
{
"id": 3,
"fullname": "Mike Palmer",
"children": []
}
]
How can I print out such a JSON-tree using the User models?
I have had to use tree data structures (i.e. self-referential models) before. I would consider using the Ancestry gem. It allows you to do things like enumerate descendants and paths bath to the root, making traversing your data structure significantly easier.

How to model schema for list of embedded dictionaires in python eve

I have a Document where a user has 2 addresses such as below. How would I create a schema for this in python-eve?
Also, How would I create an API request to allow a user to update only the zipcode. Do they have to repost the entire document?
{
_id: "joe",
name: "Joe Bookreader",
addresses: [
{
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
},
{
street: "1 Some Other Street",
city: "Boston",
state: "MA",
zip: "12345"
}
]
}
As far as the schema goes, this should do the trick (docs):
'addresses': {
'type': 'list',
'schema' {
'type': 'dict',
'schema': {
'street': {'type': 'string'},
'city': {'type': 'string'},
'state': {'type': 'string'},
'zip': {'type': 'string'}
}
}
}
Dot notation is supported for PATCH (update) requests, but not on lists of documents. They are trickier, and hard to do in a RESTful way. There's an open ticket for that right now, but not direct solution yet, I am afraid.

Unable to get JSON response from RoR backend using EmberJS and Ember-data

I kno this is a bit tricky question. The thing is I have connected succesfully two models with complex relationships (using joining tables between them and so on) between my Ruby on Rails backend and Ember/Ember-Data through a JSON response.
Know, the problem is I am not able to connect a third model. Its ids are embedded on another model working fine. The thing is even I am getting a working JSON response with the data indeed, but my ember-data model is not getting them for some reason on my ember controller.
This is the model I am trying to get:
Profile.js
App.Adapter.map
(
'App.Profile',
{
projects: {embedded: 'load'},
people: {embedded: 'load'}
}
);
App.Profile = DS.Model.extend
(
{
name: DS.attr('string'),
tools: DS.attr('string'),
number: DS.attr('number'),
projects: DS.hasMany('App.Project', {embedded: 'load'}),
people: DS.hasMany('App.Person', {embedded: 'load'})
}
);
The model Person.js, whose JSON response is being valid returned:
App.Adapter.map
(
'App.Person',
{
profiles: {embedded: 'load'},
projectsCreated: {embedded: 'load'},
projects: {embedded: 'load'},
friends: {embedded: 'load'}
}
);
App.Person = DS.Model.extend
(
{
name: DS.attr('string'),
place: DS.attr('string'),
email: DS.attr('string'),
password: DS.attr('string'),
academic: DS.attr('string'),
professional: DS.attr('string'),
profiles: DS.hasMany('App.Profile', {embedded: 'load'}),
knowledge: DS.attr('string'),
projectsCreated: DS.hasMany('App.Project', {embedded: 'load'}),
projects: DS.hasMany('App.Project', {embedded: 'load'}),
friends: DS.hasMany('App.Person', {embedded: 'load'}),
iconUrl: DS.attr('string')
}
);
The serializers profile_serializer.rb and person_serializer.rb used for each one:
class ProfileSerializer < ActiveModel::Serializer
attributes :id,
:name,
:tools,
:number
has_many :projects, ember: :id
has_many :people, ember: :id
end
class PersonSerializer < ActiveModel::Serializer
attributes :id,
:name,
:place,
:email,
:password,
:academic,
:professional,
:knowledge,
:icon_url
has_many :friends, embed: :id
has_many :projects_created, embed: :id
has_many :projects, embed: :id
has_many :profiles, embed: :id
end
And, at the end, the JSON responses:
GET http://localhost:3000/people
{
"people": [
{
"id": 1,
"name": "Daniel",
"place": "Ireland",
"email": "daniel#example.com",
"password": "123456",
"academic": "Computing Engineer",
"professional": "Fundecor",
"knowledge": "html, css, javascript, jquery, ember",
"icon_url": "http://imageshack.us/a/img196/6619/xckl.jpg",
"friend_ids": [
2,
3
],
"projects_created_ids": [
1
],
"project_ids": [],
"profile_ids": [
1,
3,
5
]
},
{
"id": 2,
...
},
{
"id": 3,
...
}
]
}
And the next step is query for this profile_ids whose right answer is:
GET http://localhost:3000/profiles?ids%5B%5D=1&ids%5B%5D=3&ids%5B%5D=5
{
"profiles": [
{
"id": 1,
"name": "Frontend",
"tools": "html, css, javascript, jquery",
"number": 0,
"projects": [],
"people": [
{
"id": 1,
"name": "Daniel",
"place": "Ireland",
"email": "daniel#example.com",
"password": "123456",
"academic": "Computing Engineer",
"professional": "Fundecor",
"knowledge": "html, css, javascript, jquery, ember",
"icon_url": "http://imageshack.us/a/img196/6619/xckl.jpg",
"friend_ids": [
2,
3
],
"projects_created_ids": [
1
],
"project_ids": [],
"profile_ids": [
1,
3,
5
]
}
]
},
{
"id": 2,
"name": "Mobile Developer",
...
},
...
]
}
All the profiles entries are returned. But the thing is, when I try to get this through my controller or my route, the result getting on the browser console (firebug or similar) is empty. Every field of person is right filled, including profile_ids, but not the profile model itself.
Maybe, if you want to have the whole code itself, you can check it on https://github.com/neil89/project-on. Thank you a lot in advance for your answers.

Resources