Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

has_many through self_and_descendants #9

Closed
zlw opened this issue Jun 29, 2012 · 7 comments
Closed

has_many through self_and_descendants #9

zlw opened this issue Jun 29, 2012 · 7 comments

Comments

@zlw
Copy link
Contributor

zlw commented Jun 29, 2012

I've got 2 models: User and Contract. User has many contracts but he should be able to see all of his and his descendants contracts. I tried something like this:

class User < ActiveRecord::Base
  acts_as_tree
  has_many :contracts, through: :self_and_descendants
end

class Contract < ActiveRecord::Base
  belongs_to :user
end

but i'm getting:

1.9.3p194 :058 > User.find(3).contracts
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 3]]
SystemStackError: stack level too deep
    from gems/activerecord-3.2.6/lib/active_record/reflection.rb:530

is it possible to do such thing?

@zlw
Copy link
Contributor Author

zlw commented Jun 29, 2012

well, it's definitely not my day ;)

class User < ActiveRecord::Base
  has_many :contracts, finder_sql: proc {
    Contract.where(user_id: self_and_descendant_ids).to_sql
  }
end

I'm sorry to have bothered you :)

@zlw zlw closed this as completed Jun 29, 2012
@zlw zlw reopened this Jun 30, 2012
@zlw
Copy link
Contributor Author

zlw commented Jun 30, 2012

well, it isn't great (even good) solution, cause it doesn't work with default has_many behavior. has_many will use default query when for example User#contracts.where(foo: :bar)

It should work just fine if self_and_descendants (and others) would be has_many :through relation, not habtm. It would be nested has_many :through which works fine in rails3. Is it possible to convert them?

@mceachen
Copy link
Collaborator

mceachen commented Jul 7, 2012

OK, I'll see how horrible it is (because I agree, your finder_sql is a nasty hack to have to do, and won't scale well).

@mceachen
Copy link
Collaborator

mceachen commented Jul 9, 2012

OK, try out 3.1.0 -- we're now using has_many :through.

@mceachen mceachen closed this as completed Jul 9, 2012
@zlw
Copy link
Contributor Author

zlw commented Jul 10, 2012

nice :) I'll try out new version withnin few days and I'll write is it working fine

@zlw
Copy link
Contributor Author

zlw commented Jul 10, 2012

well, it does not work

has_many :contracts, through: :self_and_descendants

and i'm still getting

1.9.3p194 :008 > User.find(1).self_and_descendant_contracts
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
SystemStackError: stack level too deep
    from ~/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.6/lib/active_record/reflection.rb:530

@mceachen mceachen reopened this Jul 20, 2012
@mceachen
Copy link
Collaborator

OK, I wrote an example in the specs and added support for your use case, but not using the has_many through, but by a different collection. This code is in 3.2.1.

class User < ActiveRecord::Base
  acts_as_tree 
  has_many :contracts
  def indirect_contracts
    Contract.where(:user_id => descendant_ids)
  end
end

class Contract < ActiveRecord::Base
  belongs_to :user
end

How's that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants