How to retrieve single record through chained associations


#1

Hi

I have a standard associations belongs_to, has_many :through

class Shop < ActiveRecord::Base
has_many :show_categories
has_many :categories, :through => :shop_categories
end

class Category < ActiveRecord::Base
has_many :shop_categories
has_many :shops, :through => :shop_categories
end

class ShopCategory < ActiveRecord::Base
belongs_to :shop
belongs_to :category
end

There is one root category with hierarchical data for shops.
shop_categories are holding some common fields for shop and category.
mixed one record for one shop and category. So, for 100 categories, in
shop_categories are 200 records, one for each shop.

For this example I have 2 shops.

Shop.first.category.find(10).shop_categories Rails are returning 2
shop_categories records one for each shop. Something is wrong with
associations because it should find in shop_categories all records for
first shop.

What I need is to retrieve only one record from shop_categories for
corresponding association.
I have tried has_one :shop_category but it returns not one but first and
always same never less if I try
Shop.find(1).category.find(10).shop_categories or
Shop.find(2).category.find(10).shop_categories

So, what is really happening with this association?
I realy can not guess, and I have tried all sort of things with no
results.

Logically this kind of chaining
Shop.find(2).category.find(10).shop_categories should collect and join
appropriate associations and return data only for shop 2.

Could any one give some clues? Or clarify this kind of relation. Maybe
there is another way to retrieve this single data?

Thanks,
Tod


#2

Hi Tod

For finding the category 10 of shop 1, the following should work by
using
Activerecord associations

Shop.find(1).categories.find(10)
or
Shop.find(1).categories.find(:first, :conditions => ‘category = 10’)

rainer

Dharmdip R. wrote:

end

first shop.
results.
Tod

Posted via http://www.ruby-forum.com/.


View this message in context:
http://www.nabble.com/how-to-retrieve-single-record-through-chained-associations-tp22389318p22389815.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.


#3

On Mar 7, 4:39 pm, Tod T. removed_email_address@domain.invalid wrote:

Logically this kind of chaining
Shop.find(2).category.find(10).shop_categories should collect and join
appropriate associations and return data only for shop 2.

That’'s not really how it works - once you do that find(10) you get a
perfectly ordinary instance of Category (ie the stop_categories is
just scoped to the category - not the shop.

I’m not sure why you’re doing this at all - why not Shop.find
(2).shop_categories.find_by_category_id(10) (or
find_all_by_category_id if you want all of them)

Fred


#4

Hi rainer54

Actually

Shop.find(1).categories.find(10) and
Shop.find(1).categories.find(:first, :conditions => ‘category_id = 10’)

are the different ways to retrieve same category record in association
with shop 1.

But going further with association I need to retrieve records from
shop_categories, so doing this

Shop.find(1).category.find(10).shop_categories

returns two records associated to two shops and category #10 from
shop_categories. And no matter if I try Shop.find(1)… or
Shop.find(2)… it gives me same results from shop_categories.

I need to use Rails 2.1 but I don’t think so that is some problem from
within Rails.

Tod

rainer54 wrote:

Hi Tod

For finding the category 10 of shop 1, the following should work by
using
Activerecord associations

Shop.find(1).categories.find(10)
or
Shop.find(1).categories.find(:first, :conditions => ‘category = 10’)

rainer


#5

can u tell me online tutorial…???

On Mar 7, 10:55 pm, Frederick C. removed_email_address@domain.invalid


#6

Hi Frederick

Thanks for answer.

I’m just trying to investigate why it is not chained whole over all
associations. I think that each association shuold act as maybe proxy
and pass from begining Shop.find(1) till the end of this chainings and
pass Shop record.

It sounds to me naturally way of living this kind of chainging. But I is
it is not.

I’m just guessing but I think this kind of behaviour is in DataMapper,
am I right?

Tod

Frederick C. wrote:

On Mar 7, 4:39�pm, Tod T. removed_email_address@domain.invalid wrote:

Logically this kind of chaining
Shop.find(2).category.find(10).shop_categories should collect and join
appropriate associations and return data only for shop 2.

That’'s not really how it works - once you do that find(10) you get a
perfectly ordinary instance of Category (ie the stop_categories is
just scoped to the category - not the shop.

I’m not sure why you’re doing this at all - why not Shop.find
(2).shop_categories.find_by_category_id(10) (or
find_all_by_category_id if you want all of them)

Fred


#7

On Mar 7, 6:08 pm, Tod T. removed_email_address@domain.invalid wrote:

am I right?

don’t know about DataMapper. In activerecord as soon as you call find
you’ll get a normal record/array of records. if you just want
something that adds some extra conditions then you may be interested
in named_scope. The other thing is that (in active record) scopes
scope a particular table, so when you do Shop.find(1).categories then
the categories proxy there is scoping finds on Category to those with
the appropriate shop_id - it’s not magic thing across everything with
a shop_id column.

Fred

Fred


#8

can u tell me online tutorial…???


#9

ok - misunderstood this

The solution is already given by Fred


#10

I know that this is not so good solution, but I could not figured out
over way to get this value. It is realy over kill for server. And It
would get harder if there are more values that I need to keep in
merchant_categories.

oops, should be shop_categories

Tod

ps. hmm, here posts don’t have ‘edit’ option


#11

Hi and thanks,

yes this works Shop.find(2).shop_categories.find_by_category_id(10)

In shop_categories table I have field ‘active’ to mark that a category
is visible/active for the shop.

So what is the best way to retrieve this value for shop’s category?

In Category model I have defined ‘active’ so I can fetch with
@category.active or
@categories.each do |category|
<%= category.name %>
<%= category.active %>
end

def active
self.merchant_categories.find_by_category_id(id).active
end

I know that this is not so good solution, but I could not figured out
over way to get this value. It is realy over kill for server. And It
would get harder if there are more values that I need to keep in
merchant_categories.

Is there a better way to do it?

Tod

Frederick C. wrote:

On Mar 7, 6:08�pm, Tod T. removed_email_address@domain.invalid wrote:

am I right?

don’t know about DataMapper. In activerecord as soon as you call find
you’ll get a normal record/array of records. if you just want
something that adds some extra conditions then you may be interested
in named_scope. The other thing is that (in active record) scopes
scope a particular table, so when you do Shop.find(1).categories then
the categories proxy there is scoping finds on Category to those with
the appropriate shop_id - it’s not magic thing across everything with
a shop_id column.

Fred

Fred


#12

Hi,

I see that nobody knows how to do better way.

So maybe someone could suggest different model design that I can do
@category.active

And just to avoid calling this
self.merchant_categories.find_by_category_id(id).active

def active
self.merchant_categories.find_by_category_id(id).active
end

instead to call
self.merchant_category.active

Thanks,
Tod

Tod T. wrote:

Hi and thanks,

yes this works Shop.find(2).shop_categories.find_by_category_id(10)

In shop_categories table I have field ‘active’ to mark that a category
is visible/active for the shop.

So what is the best way to retrieve this value for shop’s category?

In Category model I have defined ‘active’ so I can fetch with
@category.active or
@categories.each do |category|
<%= category.name %>
<%= category.active %>
end

def active
self.merchant_categories.find_by_category_id(id).active
end

I know that this is not so good solution, but I could not figured out
over way to get this value. It is realy over kill for server. And It
would get harder if there are more values that I need to keep in
merchant_categories.

Is there a better way to do it?

Tod

Frederick C. wrote:

On Mar 7, 6:08�pm, Tod T. removed_email_address@domain.invalid wrote:

am I right?

don’t know about DataMapper. In activerecord as soon as you call find
you’ll get a normal record/array of records. if you just want
something that adds some extra conditions then you may be interested
in named_scope. The other thing is that (in active record) scopes
scope a particular table, so when you do Shop.find(1).categories then
the categories proxy there is scoping finds on Category to those with
the appropriate shop_id - it’s not magic thing across everything with
a shop_id column.

Fred

Fred