Render JSON and pair records from model - ruby-on-rails

I am working with rails API , and I want to render JSON file but with specific way.
I have a model with named Store, and in this model, i have records like State and City. My problem is that I want render JSON to looks like this:
{
"Arizona": [
"Phoenix",
"Tucson"
],
"California": [
"Anaheim",
"Los Angeles",
"San Diego",
"San Francisco"
],
"Colorado": [
"Denver"
],
}
I may have in model many records with the name Colorado or with the name California, but every California record have its own city name, for example:
this is my model
| state | city |
-----------------------
|California| Anaheim |
|Colorado | Denver |
|California| San Diego|
and so on ..
so I want to pair every city that belongs to the unique state, so my JSON would show only one time the State name .
any suggestion?

Try this:
Model.select(:state, :city).group{|add| address.state}
This will return:
{"California" => [ModelObject2, ModelObject2 ], "Colarado" =>
[ModelObject1]}
Now we need to replace second object part with the city name so loop over the second part and get city from that object and then to_json to convert into json object.
Model.select(:state, :city).group{|add| address.state}.each{|_, v| v.replace(v.map {|add| add.city})}.to_json
Hope this will help you!!
ref

Related

How to edit a serialized array with known keys

I came across this question on how to edit serialized columns in Rails, where the keys are unknown.
In my case, I want to be able to edit an array of hashes where the keys are actually known, in the serialized attribute.
An example:
class Person
serialize :addresses
end
Where in Addresses would be an array of hashes:
{
line_1: "1 First Street",
line_2: "Apt 202",
city: "Tampa",
state: "FL",
zip: "12313"
}
And since I would know the index of this hash within the array with the each_with_index on a show view, I want to be able to edit the information in an edit or a new form view.

Group by date and then by city on Rails

I have an api that its output must look like:
[
{
"store": "store",
"date": "2020/05/03",
"address": {
"city": "city1"
"address_line_1": "address"
},
"sales_count": 10,
},
{
"store": "store",
"date": "2020/05/03",
"address": {
"city": "city2"
"address_line_1": "address"
},
"sales_count": 21,
},
]
I know how to handle the grouping and the sales count, but I'm having issues with grouping by city
Store.first.sales.group(:date).count would be the sales_count but I'm not sure how to include the group by address.
Taking into account that address = Store.first.sales.first.address
This means that a store has many sales and each sale has an address.
Since you're not only just want to count sales but also return data, then you should prefer PARTITION BY to GROUP BY.
You can PARTITION BY combine date, address:
SELECT store, date, address,
COUNT(sales) OVER (PARTITION BY date, address) AS sales_count
FROM _
Beside that, if you do nothing with data but return them, then the best practice is just call sql directly from adapter (so we avoid the creation of ActiveRecord model objects was causing all sorts of memory contention problem)
result = ActiveRecord::Base.connection.execute(
"SELECT store, date, address,
COUNT(sales) OVER (PARTITION BY date, address) AS sales_count
FROM _"
)
result.each do |msg|
# json serialize ???
end

Ruby - Parse out a list of locations cities, then take that list of cities and parse out the locations of each one

I'm currently trying to create a directory page for my business locations. I can easily just list out all locations, but would much rather list out the states of the locations, then underneath list out the location cities in that state. Then finally underneath the state, list out the location names.
I'm currently getting all locations with the line below.
#locations = #brand.locations.all
Then I create two blank arrays for states and cities.
#states = []
#cities = []
Once I've created the arrays I want to iterate through the locations to append the states and cities to their appropriate arrays.
#locations.each do |location|
#states << location.state
#cities << location.city
end
How could I append the locations to their appropriate cities in the city array? I was considering using a hash within the #cities array, but have gotten stuck from there. Sorry if this seems like a basic question.
Have a look at #group_by and #map:
Hash[#locations.all.group_by(&:state).map{|k,v| [k, v.group_by(&:city)]}]
This generates something like:
{
"NY": {
"Schenectady": [ ... locations in schenectady new york ... ],
"Manhattan": [ ... locations in manhattan new york ...]
},
"TX": {
"Austin": [ ... locations in austin texas ... ]
}
}

Ruby on Rails search with array of values to find in multiple fields (datatables)

I implemented datatables like proposed on the http://railscasts.com/episodes/340-datatables and it works just fine. Unfortunately it doesnt concern the point of searching with spaces in the input field. If I implement it with the search function processing it with javascript it works just fine.
So what I want to do is search on the database on many fields where the parameters of the sql are splitted by space (dynamic size of parameters)
eg. "name1 street city" -> this means returned objects must contain all three "name1", "street", "city" in one of the objects fields.
Here's an example:
Person :name, :address, :city, :country
Person("Peter Mayer", "Some Street 111", "New York", "United States")
if a user searches with "Peter York" it should find the object
if a user searches with "Peter Los Angeles" it should not find anything
if a user searches with "111 Mayer States York" it should find the object
okey, i could write many different sql's respecting the amount of params but that istn't so nice
Is there an easy way to solve that?
Filtering after searching with just the first param isn't an option since pagination wouldnt work anymore
You could do the following:
Join all the attributes that must be found in one string
search_attributes = [person.name1, person.address, person.city, person.country].join(' ')
for your example search_attributes would be equal to "Peter Mayer Some Street 111 New York United States"
Then you iterate over every string in the query and make sure it is found in search_attributes using .include?, and return a record only if all strings in the sent query are found in search_attributes
I did it like this now:
searchData = params[:sSearch].split(" ")
searchString = "1 = 1"
searchParams = {}
i = 0
searchData.each do |searchParam|
searchString += " AND (persons.name like :search"+i.to_s+" or persons.address like
:search"+i.to_s+" or persons.city like :search"+i.to_s+" or persons.country like
:search"+i.to_s+"+")"
searchParams["search#{i}".to_sym] = "%"+searchParam+"%"
i += 1
end
Person.where(searchString, searchParams)

Ruby on Rails: How to store form data

I have a state field that stores the value as 2 characters. For example, Alabama is saved as AL, Alaska is saved as AK, Arizona is saved as AZ, etc. In the show.html.erb, how do I display the long name for the state such as Alabama instead of just showing AL? Is this possible or should I just store the long name in the database such as Alabama, Alaska, Arizona, etc?
Write a method that would output long name of a stateand call it in show.html.erb
some_model.rb:
SomeModel < ActiveRecord::Base
STATE_CODES = {
"AL": "Alabama", "AK": "Alaska",
# add remaining 50
}
def state_human_name
STATE_CODES[self.state]
end
show.html.erb:
<%= record.state_human_name %>
EDIT: It does not help to store full names of states in your database -- you'll need short forms at least somewhere and therefore would need to add mapping between short and long forms anyway.
Is there a reason for using the 2 letter codes (e.g. a legacy database)? If not I would stick to the usual ActiveRecord idiom and have a separate "states" table linked by id. If you need the 2 letter code for display purposes, printing address labels or whatever then add add a 'state_code' attribute to the states table but don't use it as a primary key.
I put this in a comment, but I've decided it's sufficiently different that it warrants an answer.
When you're deciding where to keep your state map, consider whether you'll ever need to ship things to Canada, or further afield. If so, it's worth the effort to set up a states table, linked to a countries table.
And anyway, if your data rarely changes, it's less issue-prone to put it in the database, because code changes far more often. More frequent changes = more opportunities to mess it up. Plus, it's then trivial to sort as you like.
class State < ActiveRecord::Base
def self.get_states
##states || State.find(:all,
:include => :country,
:order => 'countries.name, long_name')
end
end
Tilendor, I notice that if I use STATE_CODES.invert, the drop-down menu selection would get out of order. For example, the first five lines of my option list is shown below:
New Hampshire
Ohio
Colorado
Minnesota
Alabama
...
In my STATES_CODES hash, I have the following listed in the order below:
"AL" => "Alabama",
"AK" => "Alaska",
"AZ" => "Arizona",
"AR" => "Arkansas",
"CA" => "California",
...
Is there a way to have the options listed in the form in the same order as the STATES_CODES? Maybe sort them alphabetically?

Resources