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
Related
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.
I wanna do something like this:
Let's say I have a array of users names ["John", "Mary"], etc...
and I wanna create a array with new User records, where name attribute is initialized by those values. What is the easiest way to do that?
Pass your array into this method:
def create_users(names):
users = []
names.each do |name|
u = User.create(:name => name)
users << u
end
users
end
This:
takes an array of names in
creates an empty array to hold the created users
creates a user for each name and adds the user to the array
returns the array
Found the answer by myself:
["john", "mary"].map{|u| User.new(name: u)}
I have a table that has alot of data inside it
I'm wanting to do something like this. To grab everything inside a column that matches something else inside another column in another table.
So #car = Cardata.find_by(#carmake)
So, #carmake will be volvo, Typed in a separate form and stored in a table.
In the table Cardata there is a massive list (about 40k records) with different cars ranging from ford to renault to volvo.
The question is. Would #car display all the records that have the word volvo inside?? Or is it the wrong way of doing this? or do i need to label it by column?
Sam
To get all of them:
#cars = Cardata.where(carmake: #carmake).all
To get just the first:
#car = Cardata.where(carmake: #carmake).first
you should be doing:
#car = Cardata.find_by_attribute_name(#carmake) # This will return the first car that matches #carmake.
Assuming attribute_name is model.
You'd do:
Cardata.find_by_model(#carmake)
If you want all the cars that matches #carmake.
You need to do:
Cardata.where(model: #carmake) # this will return an array of all cars with model #carmake.
Assuming you have a column in car data for make, I think you'd want to do something like:
#cars = Cardata.where(make: #carmake).all
User
first_name: "Johnny"
age: 15
Car
name: "Mazda"
Car
name: "BMW"
I would like results that look like
[ {"first_name": "Johnny", "age": 15, cars: [ { "name": "Mazda" }, { "name" : "BMW" } ] } ]
Is it possible to do this in Rails? So far I can get the Users car by typing johnny.cars but I'd like the data structure to also hold the values of the parent.
I was toying with the idea of using named_scopes and transient attributes but no luck so far any ideas/help is greatly appreciated.
You Could actually retrieve all the records from the other table using :includes statement
includes is magically syntax where in you can eager load all the assocaited records of a record.
Example In your case
User has_many cars
so If you do
#users = User.includes(:cars)
Now this would load all the user records and will eagerload all the cars records for each user objects
so if you loop through a user object and do
<% #users.each do |user| %>
<%= user.cars %>
<%end%>
user.cars wont fire a seperate query to fetch the all cars for the users instead it will fetch those record eager loaded using the includes clause
This technique is widely used to avoid N+1 query problem
Google for N+1 to know more on it
Hope this Help
I am trying to create a Model to pass to a gsp view. I would like to do a sub query across two tables. I have two domains, alum_profile and alum_position. alum_profile has many alum_position's. alum_position belongs to alum_profile. In SQL if I wanted to create a result set, I would have something like this:
Select count(id),
(Select CONCAT(first_name, ' ', last_name)
From alum_profile
where
alum_profile_id =alum_profile.id ) as Person
FROM alum_position
GROUP BY alum_profile_id
ORDER BY count(id) DESC
How do I do this with HQL and create a model that can be passed to a gsp View.
Thanks for your help
jason
I am using Spring Source, with MySQL and writing in groovy on grails
From what I've read of your question, you want to display a list of the Profile's names, along with how many Positions each Profile has, sorted by the number of positions, desc.
First, you need Models:
class AlumProfile {
String first_name
String last_name
def hasMany = [positions: AlumPosition]
};
class AlumPosition {
String name // I just added this, no idea what you need in here
def belongsTo=AlumProfile
};
Now you want to create a list of the AlumProfiles sorted by position count. In your controller, you need:
def allByPositionCount = {
def profiles = AlumProfile.list().sort( [compare: { a,b -> a.positions.size().compareTo( b.positions.size() ) }] as Comparator );
[ profiles: profiles ]
}
This will render the allByPositionCount.gsp with the model containing the "profiles" member that is the list of profiles in the correct order, so something like:
<g:each in="${profiles}" var="profile" >
${profile.first_name} ${profile.last_name} has ${profiles.positions.size()} positions
</g:each>
should render what you want.