I am building a webapp using Rails 3.2.8.
In this app I got three tables. Projects, Tasks and Subtasks.
Projects
id, name
Tasks
id, name, project_id
Subtasks
id, name, desc, task_id, value
I would like to get all subtasks that belongs to a project and sum up the values and group them by created_at.
This is what I try but it does not work (only get a AR relation back).
#tasks = #project.tasks.joins(:subtasks).select('sum(subtasks.value)').group('subtasks.created_at')
What am I doing wrong?
Thankful for all help!
I think you're closer than you realize.
Each of the methods in the chain you have provided result in ActiveRecord::Relation. All you need to do is call all or each or some other method to force it to execute the query.
I think you also meant to group by tasks.created_at?
Finally, I'd recommend you created a class method in the Task model to simplify this a little.
I hope that helps.
Related
I'm working on my first (kinda) big personal project and I am stuck. I have 4 tables, 3 of which have foreign keys linking into tbl_model_details. All tables are listed below.
tbl_model_details
tbl_model_type
tbl_model_name
tbl_model_scale
Ideally I want to show data through my controller with HTTP Get. I can get Postman to to return data from my controller using _context.tbl_model_details.ToList();
Currently Postman is showing the id's for the other tables, but want them to show data from other columns within those tables instead of the id.
Within SQL I was able to build this query which displays the information I would like from the other tables, Is there an equivalent that I could make to run inside my controller? Or is there a way I can use this query that I have already made?
SELECT model_scale, model_name, info, picture, model_type, part_number, amount_owned, modified, limited_addition, date_purchase, price_paid, upc
from tbl_model_details
join tbl_model_type
on tbl_model_details.type_id = tbl_model_type.type_id
join tbl_model_name
on tbl_model_details.name_id = tbl_model_name.name_id
join tbl_model_scale
on tbl_model_details.scale_id = tbl_model_scale.scale_id
Any help from you guys would be great.
Thanks
You can use Entity Frameworks LINQ Include. This will allow you to include the sub-models in the same query:
_context.tbl_model_details
.Include(details => details.tbl_model_type)
.Include(details => details.tbl_model_name)
.ToList();
Without knowing your relationships, DBSet and Model setups, I can say that the statement will look exactly like the one I mentioned, but this may help you get on the right track.
This will allow you to later retrieve data from the sub-models:
#Model.tbl_model_scale.model_scale;
I've got a bit of code that I'm looking at the moment :
User.includes([:profile => :schedule]).where('...')
This loads all profiles and their schedules. So the query produced by this is select * user fields, select * profile fields, select * schedule fields
I'm filtering out users based on one field from profile and based on one field from profiles schedule but this above statement is selecting all the fields from all of these.
So I tried to do it with joins :
User.joins(:profile).joins('profiles.schedule').where('....').select('....')
This is throwing out error. I'm a former Java developer, still learning the rails stuff.
This should work:
User.joins(profile: :schedule).where('....').select('....')
If you've set your Profile model to have the association Schedule using the has_many through association then you can just use this:
User.joins(:schedule).where('...')
Try this:
User.joins(profile: [:schedule]).where('...')
or
User.joins(profile: :schedule).where('...')
(I tried posting this to the CFWheels Google Group (twice), but for some reason my message never appears. Is that list moderated?)
Here's my problem: I'm working on a social networking app in CF on Wheels, not too dissimilar from the one we're all familiar with in Chris Peters's awesome tutorials. In mine, though, I'm required to display the most recent status message in the user directory. I've got a User model with hasMany("statuses") and a Status model with belongsTo("user"). So here's the code I started with:
users = model("user").findAll(include="userprofile, statuses");
This of course returns one record for every status message in the statuses table. Massive overkill. So next I try:
users = model("user").findAll(include="userprofile, statuses", group="users.id");
Getting closer, but now we're getting the first status record for each user (the lowest status.id), when I want to select for the most recent status. I think in straight SQL I would use a subquery to reorder the statuses first, but that's not available to me in the Wheels ORM. So is there another clean way to achieve this, or will I have to drag a huge query result or object the statuses into my CFML and then filter them out while I loop?
You can grab the most recent status using a calculated property:
// models/User.cfc
function init() {
property(
name="mostRecentStatusMessage",
sql="SELECT message FROM statuses WHERE userid = users.id ORDER BY createdat DESC LIMIT 1,1"
);
}
Of course, the syntax of the SELECT statement will depend on your RDBMS, but that should get you started.
The downside is that you'll need to create a calculated property for each column that you need available in your query.
The other option is to create a method in your model and write custom SQL in <cfquery> tags. That way is perfectly valid as well.
I don't know your exact DB schema, but shouldn't your findAll() look more like something such as this:
statuses = model("status").findAll(include="userprofile(user)", where="userid = users.id");
That should get all statuses from a specific user...or is it that you need it for all users? I'm finding your question a little tricky to work out. What is it you're exactly trying to get returned?
I have three tables:
Stories (id, category_id, sub_category_id, name, story),
Categories (id, parent_id, lft. rght, name),
SubCategories (id, name)
They are properly related and all is working fine. But now I need to find stories which belongs to specified category and/or sub_category, by name autocompleate dialog. Example: user entered "dog bone" and must search for such a name in categories/subcategories and after find all stories whitch belongs to found categories. No problem when doing many finds, but in SQL I can make one query. Can this be done in CakePHP in one find ?
Thank you very much!
there are a few options for doing this, some of them below
a) linkable behavior - https://github.com/Terr/linkable/wiki
b) bindModel - http://mark-story.com/posts/view/using-bindmodel-to-get-to-deep-relations
c) adhoc-joins http://bakery.cakephp.org/articles/view/quick-tip-doing-ad-hoc-joins-in-model-find
read up on them and see what suites your needs best.
either you solve it with the table assocations or you use "containable" behavior.
"Containable" Behavior is very easy to use and easy to implement.
Containable Behavior in Cookbook
imagine the following problem in grails
you have some kind of audit trail domain class with numeric properties. For instance a class in which the current burndown value of your scrum project is written:
class burndown {
Date createDate
int value
}
Your projects uses this class to store the current burndown value each time you update a task - this means several times a day.
Now you want to plot a diagram with the last stored value for each day.
An SQL statement for this could look something like
select
*
from
table
where
id in (
select
max(id)
from
table
group by
TO_CHAR(create_date,'yyyyddmm')
)
Now my question: how do you do such a query in grails?
If I have to use such an SQL statement, how to I avoid to put the table and column names hard coded in the statement?
PS: this code hasn't been tested. just written down from my mind... but I guess you feel what I want to ask
For starters you'll most likely want to rename createDate to dateCreated since it's automatically set for you by Grails if you use that name, so you only need to specify values for the 'real' properties of the class. It's not important to this issue though.
If you want the most recent item by created date, there are a few different ways you could do this but I think this makes the most sense:
def mostRecent = Burndown.listOrderByDateCreated(max: 1, order: 'desc')[0]
or if you retain your name
def mostRecent = Burndown.listOrderByCreateDate(max: 1, order: 'desc')[0]
This is described at http://grails.org/doc/latest/ - it's a fine manual, worthy of reading.
Not a Grails user, so below should be corrected accordingly by a Grails'ist
If domains are related, try something like:
Foo.findAllInList(Bar.list([group:'create_date']))