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.
Related
I am building up an array of products in rails. Which is working fine, but my question is...
Is there any way to update an item if it exists in the array already? So as I am looping through products, and the model is "TV-32D300B" I need to check the array to see if it exists, but it may only be a partial number like "TV-32D300" (minus the last letter).
If the is the case I want to be able to update that product with the correct details.
product = {
name: product_name,
url: product_url,
modelnumber: product_modelnumber,
category_id: category.id,
group_id: category.group_id,
image_url: image_url
}
I'm using the include? to add products to the array if a product doesn't already exist, so I am guessing I need to add a like condition to find the number.
unless products.include?(product)
products << product
end
Assuming products is an array of hashes and what you call a model is a product_name held under name key in this hash, the following would do:
existing = products.find { |p| product[:name].include? p[:name] }
if existing
# update existing
else
products << product
end
More info on Enumerable#find.
Let's say we have a resourceful Student model. I have a query regarding updating a student resource via PUT api.
If we send a put request to PUT /students/1 along with request body containing the few attributes that we want to update.
Let's the Student having many attributes like name,age,rollno,country,dob and we just want to update the country, so in the put request body we will pass something like {country: 'germany'} , some other request might pass only the dob.
How should we handle it in server side to only update the attributes passed in the body ?
The update method on your ActiveRecord objects takes an attributes hash. You can pass only one attribute, or all attributes of a model, and ActiveRecord will figure out what has changed and only update those columns and leave the rest alone.
student = Student.create(name: 'name', age: 'age', rollno: 'rollno', country: 'country', dob: 'dob')
params = { country: 'germany' } # stand-in for your actual params hash in the controller
student.update(params)
Only country will be updated, everything else will remain the same. On the next request when you update dob it works the same way.
params = { dob: '1/1/2000` }
student.update(params)
I am building an application with a database table for games. All games have different attributes, although some attributes are the same for each game, mostly name and type. I store all the attributes in a separate table so that they can be searchable. Every game has a has_many relationship to attributes.
Table games
id int primary key
name string unique
type string
Table attributes
id int primary_key
game_id int
name string
value text
For example the game "Nyan Cat Adventures in Space" (made up name) could have the following attributes:
id game_id name value
4 344 dlc 99
5 344 packages 2209
6 344 language "Space Cat"
7 344 dlc 551
I need the attributes to be fully searchable (and indexed). I would like to be able to transform the attributes into a hash so that I could access certain attributes like this: game.attributes['dlc']. Note however that some attributes can have the same name. What is the best way to achieve this, should I extend ActiveRecord::Base? Is there a function or callback I can use?
If you have a list of records like games = Game.all
and Game objects have associated DLC objects, you can do this:
game_hashes_with_dlc_info = games.map do |game|
game.attributes.merge(dlc: game.dlc.map(&:attributes))
end
in response to your comment
Given a hash like { foo: "1", foo: "2", bar: "1", bar: "2" }
that you want to turn into { foo: ["1", "2"], bar: ["1", "2"] }
hash_1.reduce({}) do |new_hash, (hash_1_key, hash_1_val)|
if new_hash.has_key? hash_1_key
new_hash[hash_1_key].push(hash_1_val)
else
new_hash[hash_1_key] = [hash_1_val]
end
new_hash
end
this has the effect of making all the hash values arrays, which may not be what you want.
You could probably use group_by to get what you want. Something along the lines of the following will probably work.
class Game < ActiveRecord::Base
has_many :game_attributes, :class_name => "Attribute"
def game_attributes
result = super
result.to_a.group_by{|a| a["name"]}
end
end
This means that game.game_attributes["dlc"] will return all Attribute objects associated with that game. This does end up hiding the active record relation so you may want to define a new method rather than override this one depending on what you intend to do.
I store an array of Section ids as integers. event.sections #=> ["1","115","130"]
There is no Events has_many Sections relationship. Maybe this is a problem. I only need id's from Section and nothing else, so I have the array of integers stored as a serialized string in Postgres.
I can do something like this, which returns an array of events:
Event.upcoming.select { |m| m.sections.include? #section.id.to_s}
Is there a way to query this to get back an ActiveRecord::Relation?
edit-----
My earlier select query is not correct, because if #section.id = "1" then it will match and select events with these id's "1", "10", "21", "100"
This is the proper select statement:
Event.upcoming.select {|e| ( e.newsletters.split(",").flatten.grep /^#{#section.id.to_s}$/ ).presence }
Using Grails, I am looping through an array in a view using a <g:each /> tag, however I want to use the values in the array as a reference to foreign key in another table in the database, in the same loop.
Is it possible to create a string of variable references to other tables? for example:
${productId.Users.UserId}
If I understand your question correctly, you want to do something like ...
//Assuming this is the list to run through your <g:each>
def list = ['userId1', 'userId2', 'userId3']
And assuming the values of the above list are some attribute of some table or data model you have like...
def model = [
userId1: 'John Doe',
userId2: 'Jane Doe',
userId3: 'Jack Doe'
]
If the above is the scenario you're thinking of, then you should be able to do something like this...
<g:each in="${list}" var="element">
${model[element]}
</g:each>
//output
John Doe
Jane Doe
Jack Doe