SQL LIKE search error only on one row of table - mysql

This is weird, it never happens to me before
Im on the rails console, because my search form is not working, for some reason when i do a search using the row called 'nombre', the search doesnt work, this is the output data:
First, I will show you my table data:
2.3.0 :035 > Item.all
Item Load (0.6ms) SELECT "items".* FROM "items"
=> #<ActiveRecord::Relation [#<Item id: 1, nombre: "Melamina Blanca", espesor: 18, material: "MDF", quantity: 14, created_at: "2016-08-04 00:56:13", updated_at: "2016-08-30 00:05:01">, #<Item id: 2, nombre: "Melamina Gris Grafito", espesor: 15, material: "Aglo", quantity: 9, created_at: "2016-08-04 00:56:13", updated_at: "2016-08-30 00:05:01">, #<Item id: 3, nombre: "Melamina Azul", espesor: 18, material: "MDF", quantity: 26, created_at: "2016-08-04 00:56:13", updated_at: "2016-08-30 00:05:01">, #<Item id: 4, nombre: "Melamina Rojs", espesor: 18, material: "MDF", quantity: 5, created_at: "2016-08-04 00:56:13", updated_at: "2016-08-30 00:05:01">]>
2.3.0 :036 >
So as you can see, the first item, the name (nombre) is 'Melamina Blanca'
If I do the search, I get the following:
item = Item.where("nombre LIKE ?", "Blanca")
Item Load (0.8ms) SELECT "items".* FROM "items" WHERE (nombre LIKE 'Blanca')
=> #<ActiveRecord::Relation []>
So I tried to search by another row, on this case called 'Material'
item = Item.where("material LIKE ?", "Aglo")
Item Load (0.5ms) SELECT "items".* FROM "items" WHERE (material LIKE 'Aglo')
=> #<ActiveRecord::Relation [#<Item id: 2, nombre: "Melamina Gris Grafito", espesor: 15, material: "Aglo", quantity: 9, created_at: "2016-08-04 00:56:13", updated_at: "2016-08-30 00:05:01">]>
I get a correct search, I tried with the other rows and all of them work, except the one I need, which is 'nombre'
Any ideas why?

I think the problem is you are searching for an exact match. To search for a pattern string, you have to use % which defines wildcards.
Try
Item.where("nombre LIKE ?", "%Blanca%")
This will look for records with names that contain "Blanca" in it.
If you want to search for names that start with "Blanca", use
Item.where("nombre LIKE ?", "Blanca%")
Or for names ending with "Blanca", use
Item.where("nombre LIKE ?", "%Blanca")
Note: Your search across material "Aglo" was successful because the material field in the record contained the exact string "Aglo".
Hope this helps!

Related

RoR, need to create recursive relationships in table associations

I'm very new to rails, and am a little stuck on the logic for this problem.
I have one table (using mysql) of employees, each of them with a manager_id key which refers to the employee they report to. So for example the employee with the title of "CEO" with an id of 1, has a manager_id of nil, and the employee with title of "CTO" has a manager_id of 1. So my records look like this
id: 1, first_name: "Bob", last_name: "Boss", title: "CEO", manager_id: null
id: 2, first_name: "Pat", last_name: "Guy", title: "CTO", manager_id: 1
id: 3, first_name: "John", last_name: "Dude", title: "VP of engineering", manager_id: 2
and my JSON structure should look like this
[
{id: 1, first_name: "Bob", last_name: "Boss", title: "CEO", manager_id: null, descendents: [
{id: 2, first_name: "Pat", last_name: "Guy", title: "CTO", manager_id: 1, descendents: [
{id: 3, first_name: "John", last_name: "Dude", title: "VP of engineering", manager_id: 2, descendents: [....]}
]},
{..more CEO descendents...}
]
I'm trying to create a nested JSON structure that starts at CEO, lists all employees that report to them, and each of those employees descendants. I was trying to write a script that creates this but I keep getting infinite recursive calls. This is what I have
#start at some root
#root = Employee.find_by title: 'CEO'
#convert to hash table
#results[0] = #root.attributes
#add direct_reports key
#results[0]["direct_reports"] = []
def getBelow(root=#root)
#reports = Employee.where("manager_id = ?", #root[:id])
if #reports.blank?
return []
else
#reports = #reports.map(&:attributes)
#reports.each do |person|
person["direct_reports"] = []
getBelow(person)
end
#reports = Employee.where("manager_id = ?", #root[:id])
root["direct_reports"] = #reports
end
return #root
end
#list = getBelow(#results[0])
If I'm passing in each new person object, shouldn't they all eventually end when #reports.blank? becomes true?
An alternative I was thinking of was to use table associations inspired by this blog post
https://hashrocket.com/blog/posts/recursive-sql-in-activerecord
but that seems a little too complicated.
Some issues in the getBelow method
You are always using #root, instead of using the param (root). So you are always starting again from the 'CEO'.
You are calling getBelow recursively but you are not using the result.
You call #reports = Employee.where("manager_id = ?", #root[:id]) twice.
You return #root.
As Jorge Najera said, there are gems that handle a tree structure easily. If you want to build it on your own, this is my suggestion:
#start at some root
#root = Employee.find_by manager_id: nil
#convert to hash table
#tree = #root.attributes
#add direct_reports key
#tree["direct_reports"] = getBelow(#root)
def getBelow(manager)
branch = []
Employee.where("manager_id = ?", manager.id).each do |employee|
node = employee.attributes
node["direct_reports"] = getBelow(employee)
branch << node
end
branch
end
This was not tested so I think you´ll get some errors, but I believe the idea is fine.

How to use Jbuilder to display parent info with child information nested underneath

I am using jbuilder in rails to generate some JSON in a rails app.
In my models, 'od_items' belong to 'od', and 'ods' belong to 'sophead'.
I want to display each 'od' of the 'sophead', and then nested under each of these, I want to display each of the 'od_items' that belong to the 'od'.
Here is my code so far:
json.ods #sophead.ods do |od|
json.od od
json.od_items od.od_items do |od_item|
json.od_item od_item
end
end
This is outputting the following JSON:
ods: [
{
od: {
id: 51,
sophead_id: 386,
created_at: "2018-03-21T15:28:48.802Z",
updated_at: "2018-03-21T15:28:48.802Z",
status: "Open"
},
od_items: [
{
od_item: {
id: 285,
od_id: 51,
qty: "1.0",
part: "CARRIAGE CHARGE",
description: "Simpson Carriage Charge",
created_at: "2018-03-21T15:28:48.823Z",
updated_at: "2018-03-21T15:28:48.823Z"
}
},
{
od_item: {
id: 284,
od_id: 51,
qty: "1.0",
part: "MISCELLANEOUS",
description: "Split Box Charge",
created_at: "2018-03-21T15:28:48.816Z",
updated_at: "2018-03-21T15:28:48.816Z"
}
}
]
}
],
The problem is that I want 'od_items' to be nested inside the 'od' that it relates to, instead it appears next to it.
This should be pretty simple to sort out, but I cant find anything online.
(First question on Stack overflow - Thanks very much in advance)
If your #sophead.ods is a collection of hashes, you can easily achieve it merging the od element with its od_items:
json.ods #sophead.ods do |od|
json.od od.merge(od_items: od.od_items)
end
Since it seems that these are ActiveRecords:
json.ods #sophead.ods do |od|
json.od od.as_json.merge(od_items: od.od_items.map(&:as_json))
end
According to the README, another way to obtain the same result is to use json.merge!:
json.ods #sophead.ods do |od|
json.od do
json.id od.id
json.sophead_id od.sophead_id
json.created_at od.created_at
json.updated_at od.updated_at
json.status od.status
json.merge! { od_items: od.od_items.as_json}
end
Another approach which assures better performances would be to use ActiveModelSerializer instead.
class OdSerializer < ActiveModelSerializers::Model
attributes :id, :sophead_id, :created_at, :updated_at, :status
has_many :od_items, serializer: OdItemSerializer
end
class OdItemSerializer < ActiveModelSerializers::Model
attributes :id, :od_id, :qty, :part, :description, :created_at, :updated_at
end
# And in the controller
render json: #sophead.ods, each_serializer: OdSerializer

Unable to save/update field with desired string value

I have a model called SystemState. Following is the migration that created this table:
create_table :system_states do |t|
t.string :code
t.timestamps
end
But, even if code column is of string type, when I do the following:
> SystemState.first
> #<SystemState id: 1, code: 0, created_at: "2017-03-14 10:19:45", updated_at: "2017-03-14 10:28:33">
> SystemState.find(1).update_attributes(code: "system_alert_notification")
> SystemState.first
> #<SystemState id: 1, code: 0, created_at: "2017-03-14 10:19:45", updated_at: "2017-03-14 10:29:43">
As can be seen, it always updates it as 0(integer).
Is the column name reserved or something? Keen to know the cause of above.
Here are some possibilities :
1) May be code is a reserved word in mysql
2) Also, I'm sure, the column in your db is of integer type. Change it to string and it should work.

Is .create method adding nil value if it fails to recognize an integer in Rails 4

In my controller, I need to pluck a single, matching integer value and then create a record with that value in another table. In action, it looks like this:
if Participation.where(ranking: "1")
first = PointsAllocation.where(game_id: params[:game_id]).where(place: "1").pluck(:points)
Stack.create(game_id: params[:game_id], user_id: current_user.id, chips: first)
else
end
I have tested in the console that the first variable is definable. If I run PointsAllocation.where(game_id: "1").where(place: "1").pluck(:points), it will return:
SELECT "points_allocations"."points" FROM "points_allocations" WHERE "points_allocations"."game_id" = 1 AND "points_allocations"."place" = 1
=> [10]
Ok, so it is correctly plucking what looks like an integer value for Points. I then want to use this points value and send it to the Chips column in the Stack table. When I run this, it will add a nil record even though first is defined, like so:
<Stack id: 1, game_id: 1, user_id: 1, chips: nil>
In troubleshooting, I thought maybe the issue here is that even though it looks like an integer (and Chips, I should add, is a t.integer attribute), maybe it's accidentally a string or something from pluck. So let's map this to an integer to be safe by adding map(&:to_i) after the pluck.
When I do that, it gets weirder, as it now returns:
<Stack id: 9, game_id: 1, user_id: 1, chips: 0>
So when I convert it to an integer, it changes 10 to a 0 and adds it to the table.
Where am I going wrong?
You may resolve it loading only one object instead ActiveRecord::Association:
first = PointsAllocation.where(game_id: params[:game_id]).where(place: "1").first
points = first.points
Stack.create(game_id: params[:game_id], user_id: current_user.id, chips: points)
Problem is that AR trying convert incorrect values if they type different with column type:
Stack.create(chips: 10)
#=> <Stack id: ..., chips: 10>
Stack.create(chips: [10])
#=> <Stack id: ..., chips: nil>
Stack.create(chips: "10")
#=> <Stack id: ..., chips: 10>
Stack.create(chips: "first")
#=> <Stack id: ..., chips: 0>

Argument error in collect object Rails 3

Guys I'm using a select() tag in .html.erb file as follows
<%= select(:hfi_id, b.beneficiaryloans.collect { |h| [User.find(h.hfi_id).firstname, h.hfi_id] }) %>
what's wrong in this statement? actually it is giving an error called
wrong number of arguments (2 for 3) - error for above line
But same thing I executed in irb console, it's working fine like
irb(main):012:0> me=Beneficiary.find(1)
=> #<Beneficiary id: 1, firstname: "Mohan", lastname: "Bairwa", address: "1399 m.k.b jagatpira", age: 24, sex: "Male", total_members: 1, cso_id: 123, project_id: 17, remarks: nil, status_id: 4, created_at: "2011-11-07 09:39:24", updated_at: "2011-11-07 09:55:07">
irb(main):018:0> me.beneficiaryloans.collect {|h|User.find(h.hfi_id).firstname,h.hfi_id]}
=> [["Gruh", 117]]
using irb console I'm getting correct result
=> [["Gruh", 117]]
but when I put it in .html.erb file, It's giving argument error. How to solve this?
Look at this. select method has 3 obligatory parameters and you provide only two..