0

I have two tables

users
-------
id
name
organization_id


organizations
----------
id
org_name
org_unique_num
abc
xyz

organization_id in users table is foreign key to organizations table's id

class Organization
  include DataMapper::Resource
  property :id, Serial
  property :org_name, String
  property :org_unique_num, Integer
  property :abc String
  property :xyz String
  has n,    :users 
end

class User
  include DataMapper::Resource
  property :id, Serial
  property :name, String
  property :organization_id, Integer
  property :age, Integer
  belongs_to :organization 
end

I want to grab the user's record with joining Organization table where user's age > 25. So the result should look like

user_id    name    organization_id    org_name   org_unique_num    age
12         John       356              ATT           76763          38
35         Lisa       981              IBM            2376          28

So how can I achieve this? Please note I dont want column abc and xyz in the result.

User.all(:age.gt => 25) 

This will just give me users with age >25, but I want to grab user's org info as well. Is it possible to do it one statement? or will have to do it in multiple steps. Like collecting all user_id then pass to Organization model to with id in().. that would be ugly.

Any help will be appreciated.

JVK
  • 3,782
  • 8
  • 43
  • 67

1 Answers1

2

DataMapper will do all join job for you.

you do not need to extract organizations for each user, this is done automatically.

So, you simply fetch your users with this: User.all(:age.gt => 25)

And each user will have its organization attached to it:

User.all(:age.gt => 25).each do |user|
  p user.name
  # organization not yet fetched, only referenced
  p user.organization
  # now organization are fetched
  p user.organization.id       # display org ID
  p user.organization.org_name # display org name
  # etc
end

Regard "i do not need abc and xyz", if they are Text columns, DataMapper will load them lazily, meant the data will be fetched only when requested via user.abc and user.xyz

  • @silvu thank you so much. It worked. By the way, is there any way to have organization as "eager-load" – JVK Dec 01 '12 at 01:50
  • What about if I write a method in User class. For e.g. `def getwithorg query finalhash = {} r = all(query) r.each do |user| finalhash[user.id] = user.organization.org_name ..... end finalhash end` – JVK Dec 01 '12 at 01:53
  • or monkeypath `all` method with above method. what do you suggest – JVK Dec 01 '12 at 01:57
  • 1
    @JVK, DataMapper using so called "Strategic Eager Loading", meant it will "load" everything(users and related organizations) with a single query, just like you are doing with a JOIN query. And when you call `user.organization` it wont hit one more redundant query(like other ORMs do) –  Dec 01 '12 at 02:01
  • you can as well add class methods and put various filters into it then call it `Users.meth_name` –  Dec 01 '12 at 02:02
  • Thank you @sivlu. I selected your answer. By the way, is there any GOOD documentation with example somewhere of ruby-datampper. It suck as far as proper documentation is concerned. – JVK Dec 01 '12 at 02:05