I'm trying to make a "not simple" query using ActiveRecord:
ChatRoom.first.as_json(include: {
chat_room_members: {
include:{
user: {
include: [
hero_page: {
only: [:torch_id]
},
card: {
only: [:crop_y]
}
]
}
}}})
In the model, a ChatRoom has many ChatRoomMembers, that has an User, that has a HeroPage and a Card.
The problem is that ActiveRecord completely ignores the argument card. More specifically, ignores the all arguments after the first argument inside user: include{}:
{
"id" =>22,
"chat_room_members" => [
{
"id" =>7,
"user" => {
"id" =>22,
"hero_page" => {
"torch_id" =>"superhero23"
},
}
}
]
}
But if I remove the only argument from either hero_page or card, ActiveRecord show everything fine. Exemple:
[...]
include: [
hero_page: {
only: [:torch_id]
},
:card
]
[...]
Other weird fact is that I can type anything (respecting syntax) in the second argument and in causes no error. Example:
[...]
include: [
hero_page: {
only: [:torch_id]
},
this: {
only: [:doesnt, :cause, :error]
}
]
[...]
Just like in the first example, shows only hero_page and ignore the other parameter, this, that doesn't even exists.
Does someone know why the second argument is ignored in those cases??
user.include needs to be hash not an Array as you have done currently.
Related
I have following two array of hashes. I am trying to remove the record from doctor array hash whose doctor_patient_id doesnt not exist in doctor_patient_id array of patient_and_doctor array of hash.
doctor = [
{ :doctor_patient_id=>"abc",
:doctor_id=>"d1"
},
{ :doctor_patient_id=>"def",
:doctor_id=>"d2"
},
{ :doctor_patient_id=>"ghi",
:doctor_id=>"d3"
}
]
patient_and_doctor = [
{ :patient_id=>"11e8f37477ab7028a66b210b9699def9",
:doctor_patient_id=>[ "def", "zkj", "cps" ]
},
{ :patient_id=>"11e8f37481fabfe68630f5da2e22dceb",
:doctor_patient_id=>[ "uio", "ghi", "jkk" ]
}
]
expected output is:
doctor = [
{ :doctor_patient_id=>"def",
:doctor_id=>”d2”
},
{ :doctor_patient_id=>"ghi",
:doctor_id=>”d3”
}
]
I tried to do something like below but no luck,
patient_and_doctor.each do |dp|
data = doctor.map {|d| d[:doctor_patient_id].include?
dp[:doctor_patient_id] }
end
How can i achieve this?
valid_ids = patient_and_doctor.flat_map { |h| h[:doctor_patient_id] }
# => ["def", "zkj", "cps", "uio", "ghi", "jkk"]
doctor.select { |h| valid_ids.include? h[:doctor_patient_id] }
# => [{:doctor_patient_id=>"def", :doctor_id=>"d2"},
# {:doctor_patient_id=>"ghi", :doctor_id=>"d3"}]
use select! instead of select if you wish to mutate your doctor array instead of returning a new one.
Following can get required answer,
doctor.select { |x| patient_and_doctor.map { |x| x[:doctor_patient_id] }.flatten.include?(x[:doctor_patient_id]) }
user.as_json(
include: [
user_purchased_packages: {
include: [
business_package: {
include: [
business: {
include: :business_address
},
package: {
include: :services
}
]
}
]
}
]
)
as I passed in the array
[:business=>{:include=>:business_address},:package=>{:include=>:services}]
So it is expecting that the business and package both objects values should come.
but I am only able to get the business object and package object is not coming.
user.as_json(include: { :user_bookings=>{include: [:business_category_service_sub_services,:business => {include: :business_address}], methods: [:date_format]}, :user_purchased_packages=>{:include=>[:business_package=>{:include=>{:package => {include: :services} , :business=>{include: :business_address} } } ] , methods: [:date_format] } }, methods: [:followers_count,:following_count,:full_name])
I'm using the elasticsearch-model gem for a model that has a has_many relationship. To match the documentation, let's say the model is Article and the relationship is has_many categories. So I wrote the customer serializer as follows (directly from the documentation):
def as_indexed_json(options={})
self.as_json(
include: { categories: { only: :title},
})
end
The serialization seems to work. The result of an example Article's as_indexed_json contains a "categories" => {"title"=> "one", "title"=> "two", "title"=> "three"} block.
What I'm struggling with, and haven't been able to find in the documentation, is how to search this nested field.
Here's what I've tried:
From the elasticsearch documentation on nested query I figured it ought to look like this:
r = Article.search query: {
nested: {
path: "categories",
query: {match: {title: "one"}}
}
}
but when I do r.results.first I get an error: nested object under path [categories] is not of nested type]...
I've tried adding changing the one line in the serializer to be: include: { categories: { type: "nested", only: :title} but that doesn't change anything, it still says that categories is not of a nested type.
Of course, I tried just querying the field without any nesting too like this:
r = Article.search query: {match: {categories: 'one'}}
But that just doesn't return any results.
Full text search like this:
r = Article.search query: {match: {_all: 'one'}}
Returns results, but of course I only want to search for 'one' in the categories field.
Any help would be much appreciated!
Rails don't create nesting mapping in elasticsearch. Elasticsearch is making the categories as object rather than nested child using dynamic mapping ("When Elasticsearch encounters a previously unknown field in a document, it uses dynamic mapping to determine the datatype for the field and automatically adds the new field to the type mapping as an object without nesting them"). For making them nested object you need to create mapping again in elasticsearch with categories as nested type, notice type as nested of category.
PUT /my_index
{
"mappings": {
"article": {
"properties": {
"categories": {
"type": "nested",
"properties": {
"name": { "type": "string" },
"comment": { "type": "string" },
"age": { "type": "short" },
"stars": { "type": "short" },
"date": { "type": "date" }
}
}
}
}
}
}
After this you can either reindex data from client or if you want zero downtime read here.
P.S: You have to delete the old mapping for particular index before creating a new one.
Ok, so it looks like: r = Article.search query: {match: {"categories.title" => 'one'}} works, but I'll leave the question open in case someone can explain what's going on with the nested thing...
I'm having problems with the Grape gem and the parameters validation.
The idea behind this is to create a complex entity using nested attributes through an API service.
I have a method to create a trip, trip have many destinations and i want to pass that destinations using a hash (using the accepts_nested_attributes_for helper).
I have this grape restriction over the parameter:
requires :destinations, type: Hash
And I'm trying to send something like this:
{ destinations => [
{ destination: { name => 'dest1'} },
{ destination: { name => 'dest2'} },
{ destination: { name => 'dest3'} }
]}
In order to build something like the structure below inside the method and get the trip created:
{ trip: {
name: 'Trip1', destinations_attributes: [
{ name: 'dest1' },
{ name: 'dest2' },
{ name: 'dest3' }
]
}}
I'm using POSTMAN chrome extension to call the API method.
Here's a screen capture:
If someone can help me i would be very grateful.
By the looks of what you are trying to send, you need to change the Grape restriction, because destinations is an Array, not a Hash:
requires :destinations, type: Array
You don't need the "destination" hash when sending the request:
{ destinations => [
{ name => 'dest1', other_attribute: 'value', etc... },
{ name => 'dest2', other_attribute: 'value', etc... },
{ name => 'dest3', other_attribute: 'value', etc... }
]}
This creates an Array of hashes.
In order to send this through POSTMAN, you'll need to modify that destinations param your sending and add multiple lines in POSTMAN. Something like:
destinations[][name] 'dest1'
destinations[][other_attribute] 'value1'
destinations[][name] 'dest2'
destinations[][other_attribute] 'value2'
destinations[][name] 'dest3'
destinations[][other_attribute] 'value3'
Hope this answers your questions. Let me know if this is what you were looking for.
I tried follow the elasticsearch doc to execute my elasticsearch with a filter but couldn't do that.
Here is my example:
class Post
def as_indexed_json(options={})
self.as_json(
only: [ :id, :title, :published ],
filter: {
bool: {
should: {
term: { published: true }
}
}
}
)
end
end
Do you guys tried this before?
Can someone give me a hand on that?
Cheers
Not so sure, but it seems to me that you have an ES syntactic error.
Could you please past the JSon sent through the ES request?
I guess that your JSon should look like this:
{
"filter": {
"bool": {
"should": [
{
"term": {
"published": true
}
}
]
}
}
}
But you send this:
{
"only" : [ "valueForId", "valueForTitle", "isPublished" ],
"filter": {
"bool": {
"should": [
{
"term": {
"published": true
}
}
]
}
}
}
Note: to more accurate answers regarding ES, inform the version of the tools you are using (ES 1.0.1 for example) and the data (the content of the JSon) sent to the ES Server, because ES had a quite important syntactic change in the past months and sometimes it is hard to figure out what your class is doing or what you have in your params (:id, :title ...).