rails combine parameters in controller - ruby-on-rails

Hopefully this is a little clearer. I'm sorry but I'm very new to coding in general. I have multiple tables that I have to query in succession in order to get to the correct array that I need. The following logic for the query is as follows:
this gives me an array based upon the store :id
store = Stores.find(params[:id])
this gives me another array based upon the param .location found in the table store where that value equals the row ID in the table Departments
department = Departments.find(store.location)
I need to preform one last query but in order to do so I need to figure out which day of the meeting is needed. In order to do this I have to create the parameter day_of_meeting found in the table Stores. I try to call it from the array above and create a new variable. In the Table Departments, I there are params such as day_1, day_2 and so on. I need to be able to call something like department.day_1 or department.day_2. Thus, I'm trying to actually create the variable by join the words "department.day_" to the variable store.day_of_meeting which would equal some integer, creating department.day_1...
which_day = ["department.day_", store.day_of_meeting].join("")
This query finds uses the value found from the variable department.day_1 to query table Meeting to find the values in the corresponding row.
meeting = Meeting.find(which_day)
Does this make my problem any clearer to understand?

findmethod can only accept parameters like Meeting.find(1) or Meeting.find("1-xx").
so, what you need is Meeting.find(department.send("day_" + store.day_of_meeting.to_s))
Hope to help!

Related

Ordering a collection by instance method

I would like to order a collection first by priority and then due time like this:
#ods = Od.order(:priority, :due_date_time)
The problem is due_date_time is an instance method of Od, so I get
PG::UndefinedColumn: ERROR: column ods.due_date_time does not exist
I have tried the following, but it seems that by sorting and mapping ids, then finding them again with .where means the sort order is lost.
#ods = Od.where(id: (Od.all.sort {|a,b| a.due_date_time <=> b.due_date_time}.map(&:id))).order(:priority)
due_date_time calls a method from a child association:
def due_date_time
run.cut_off_time
end
run.cut_off_time is defined here:
def cut_off_time
(leave_date.beginning_of_day + route.cut_off_time_mins_since_midnight * 60)
end
I'm sure there is an easier way. Any help much appreciated! Thanks.
order from ActiveRecord similar to sort from ruby. So, Od.all.sort run iteration after the database query Od.all, run a new iteration map and then send a new database query. Also Od.all.sort has no sense because where select record when id included in ids but not searching a record for each id.
Easier do something like this:
Od.all.sort_by { |od| [od.priority, od.due_date_time] }
But that is a slow solution(ods table include 10k+ records). Prefer to save column to sort to the database. When that is not possible set logic to calculate due_date_time in a database query.

How do I return a populated model when using a group by in Rails?

I was wondering if there is a way to do the following in a single query?
1) non_populated_models = PropertyPerson.select("property_people.id, count('items.recipient_person_id')").joins(:items).group('items.recipient_person_id, property_people.id')
2) populated_models = PropertyPerson.where(id: [non_populated_models])
Currently, the first group by query only returns the id, and count in the ProperyPerson object. Let's say there were 15 fields in the model and I didn't want to explicitly write them all out. Is there a way I can do this operation in a single query?
The join will work to limit the query to property_people with item and you you will get the extra column as an attr_reader.
people = PropertyPerson.select("property_people.*,
count('items.recipient_person_id') as items_count")
.joins(:items)
.group("property_people.id")
people.first.item_count

Modifying the returned value of find_by_sql

So I am pulling my hair over this issue / gotcha. Basically I used find_by_sql to fetch data from my database. I did this because the query has lots of columns and table joins and I think using ActiveRecord and associations will slow it down.
I managed to pull the data and now I wanted to modify returned values. I did this by looping through the result ,for example.
a = Project.find_by_sql("SELECT mycolumn, mycolumn2 FROM my_table").each do |project|
project['mycolumn'] = project['mycolumn'].split('_').first
end
What I found out is that project['mycolumn'] was not changed at all.
So my question:
Does find_by_sql return an array Hashes?
Is it possible to modify the value of one of the attributes of hash as stated above?
Here is the code : http://pastie.org/4213454 . If you can have a look at summarize_roles2() that's where the action is taking place.
Thank you. Im using Rails 2.1.1 and Ruby 1.8. I can't really upgrade because of legacy codes.
Just change the method above to access the values, print value of project and you can clearly check the object property.
The results will be returned as an array with columns requested encapsulated as attributes of the model you call this method from.If you call Product.find_by_sql then the results will be returned in a Product object with the attributes you specified in the SQL query.
If you call a complicated SQL query which spans multiple tables the columns specified by the SELECT will be attributes of the model, whether or not they are columns of the corresponding table.
Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
> [#<Post:0x36bff9c #attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
Source: http://api.rubyonrails.org/v2.3.8/
Have you tried
a = Project.find_by_sql("SELECT mycolumn, mycolumn2 FROM my_table").each do |project|
project['mycolumn'] = project['mycolumn'].split('_').first
project.save
end

Ruby on Rails 3: sort array based on data from ActiveRecord

I have one array, which are IDs from one ActiveRecord table.
so I would like to sort that array based on last name which is associated with that ID...how can I do that?
To clarify:
array #students=[], inside are IDs and I would like to sort by Student.find(ID).last
Thank you.
Dorijan
Without fully understanding the question, if you're given a list of id's, you can sort by last_name when you're doing the query:
Student.where("id IN (?)", #students).order(:last_name)
Of course, this assumes that #students is an array of ids and nothing else.
Responding to your comment, I'm not sure why you'd need to do that, but if your #student array is just a list of ids ignorant of the Student model and its attributes, and you would still like to order that array, you can do this:
#students = Student.where("id IN (?)", #students).order(:last_name).collect(&:id)
This will return an array of ids sorted by last name. But again, I don't really know what you have going on behind the scenes, and I'm not sure what you're asking for.
Based on your comment, you want to do the following:
Take in a list of IDs of students as input
Return a list of IDs ordered by the student's last name in the database.
You should be able to do the following:
Student.where(:id => #ids).order(:last_name).map(&:id)
Breaking this down:
where(:id => #ids) only selects Students with an ID in the ID array.
order(:last_name) sorts the results by last name.
map(&:id) takes in an array of Students and returns just the ID column. Essentially, the method in brackets (which is a shortcut for calling id for each student) is called for each student found, and the return values are assembled into a new array (which will only contain the ids).
Some gotchas:
If an ID doesn't exist in the database, it will be excluded from the results - if your result array is smaller than your input array, you may be trying to access a record that no longer exists.
If the Students table has a lot of columns, you may want to consider calling select(:id) so that you don't pull every column of the Student records from the database.
Student.find( #students ).sort_by { |s| s.last_name }

Grails criteria query retruing duplicate instances

I have a domain class called Order and that class has hasMany relation with Item class.
When I am querying for the list of orders with certain restrictions I am getting as many instances of Order as there are items.
So for example Order instance has say references to 3 instances of Item then , criteria call on Order is returning 3 duplicate instances of Order. I am not sure but if it's worth mentioning that the domain class Order has fetchMode set to "eager".
I am really puzzled with what's going on there. Any help in this regard will be greatly appreciated. Snippet of code is attached:
def clazz = "cust.Order"
def criteria = clazz.createCriteria()
println("clazz == "+Order.list())// returning correct data i.e unique instance of order
def filter = {
// trimmed down all filtering criteria for debugging
}//close filter
List results = criteria.list(max:params?.max,offset:params?.offset,filter)
results.each{Object data->
println(data.getClass())
}
println("results == "+results)
Thanks again
One solution is to use this inside your query:
resultTransformer org.hibernate.Criteria.DISTINCT_ROOT_ENTITY
If you call criteria.listDistinct instead of criteria.list duplicates will be eliminated
Criteria API is just a wrapper for constructing a SQL query. In your case, the query in question has JOINs in it (because of the eager fetching), and returns a cartesian product of Orders and their matching Items. Each row returned is included in results as a separate Order instance.
The easiest way to remove duplicates is to put all the results in a Set, like this:
def resultSet = new HashSet()
resultSet.addAll(results)
println("results == " + resultSet)
You could also use dynamic finders, as in Order.findAllBy* .Depending on how complicated your filter is, this could be easy or tough :)

Resources