Forum: Ruby on Rails belongs_to :through ?

Posted by Steven Talcott Smith (Guest)
on 2006-07-23 19:57
Suppose I have a belongs_to relationship and the thing it belongs to, 
belongs in turn to something else.

For example, I would like to do:

belongs_to :city
belongs_to: :county, :through => :city

While it is not too much trouble to do obj.city.county, there are times 
when I need to iterate through the attributes and include this 
second-order attribute.  Special code to handle this messes up my nice, 
clean iteration.

How have others accomplished this?


Steven
Posted by Josh Peek (joshpeek)
on 2006-07-24 02:56
Steven Talcott Smith wrote:
> Suppose I have a belongs_to relationship and the thing it belongs to, 
> belongs in turn to something else.
> 
> For example, I would like to do:
> 
> belongs_to :city
> belongs_to: :county, :through => :city
> 
> While it is not too much trouble to do obj.city.county, there are times 
> when I need to iterate through the attributes and include this 
> second-order attribute.  Special code to handle this messes up my nice, 
> clean iteration.
> 
> How have others accomplished this?
> 
> 
> Steven

I wish this would be added to Core. I do the same thing all the time.

For now...

Class YourObj
  def county
    city.county
  end
end
Posted by Joe (Guest)
on 2006-07-24 03:13
Yeah, I recently started playing around with has_many :through and was 
surprised that belongs_to :through doesn't exist. Seems like it should.

Joe
Posted by Joe (Guest)
on 2006-07-24 03:17
BTW, anybody file a request ticket? Looks like dev.rubyonrails.org is 
still having problems...

Joe
Posted by Rick Olson (Guest)
on 2006-07-24 03:51
(Received via mailing list)
On 7/23/06, Joe <joe@yahoo.com> wrote:
> Yeah, I recently started playing around with has_many :through and was
> surprised that belongs_to :through doesn't exist. Seems like it should.
>
> Joe

has_one :through, yes.  belongs_to :through, no.  I'll see about
getting it in for the next rails release, but I've been pretty busy
and I personally haven't needed it.  Course if someone wants to step
up to the challenge I'll be more then happy to review a patch and
commit if it's good.
Posted by Joe (Guest)
on 2006-07-24 04:21
Rick Olson wrote:
> On 7/23/06, Joe <joe@yahoo.com> wrote:
>> Yeah, I recently started playing around with has_many :through and was
>> surprised that belongs_to :through doesn't exist. Seems like it should.
>>
>> Joe
> 
> has_one :through, yes.  belongs_to :through, no.  I'll see about
> getting it in for the next rails release, but I've been pretty busy
> and I personally haven't needed it.  Course if someone wants to step
> up to the challenge I'll be more then happy to review a patch and
> commit if it's good.

Hey Rick,

Why no for belongs_to :through? I'm currently working on an app where it 
seems like it'd make sense, but perhaps I need enlightening ;).

Joe
Posted by Rick Olson (Guest)
on 2006-07-24 04:25
(Received via mailing list)
> Hey Rick,
>
> Why no for belongs_to :through? I'm currently working on an app where it
> seems like it'd make sense, but perhaps I need enlightening ;).
>
> Joe

Because belongs_to is for a foreign key thats in the current table.
If you're going :through a model, it's not the same and has_one should
be used.
Posted by Yehuda Katz (wycats)
on 2006-07-24 09:49
I wrote a some connected_to code that does:

Say you have a model called TrainingItem that belongs_to a 
:calendar_item

You can call TrainingItem connected_to :calendar_item, :date, which will 
make @training_item.date work like @training_item.calendar_item.date.

It's code that I slapped into my model, rather than pluginising, and it 
doesn't add itself to reflects_on_all_associations, but it works (rather 
crudely) for me.

This is the code:

  def self.connected_to(external, field, external_class = external)
    external_model = external.camelcase
    column field, external_model.to_c.columns.find{|x| x.name == 
field.to_s }.type
    getter_method = <<-END_GETTER
    def #{field}
      return self.#{external}.#{field} if self.#{external}
    end
    END_GETTER
    setter_method = <<-END_SETTER
    def #{field}=(to_set)
      if self.#{external}
        self.#{external}.update_attribute(:#{field}, to_set)
      else
        self.#{external} = #{external_model}.create(:#{field} => to_set)
      end
    end
    END_SETTER
    def [](field)
      self.send(field) rescue nil
    end
    def []=(field, to_set)
      eval("self.#{field} = to_set")
    end
    self.module_eval(getter_method)
    self.module_eval(setter_method)
  end

Note: .to_c is a custom method I defined that basically does 
Object.const_get(self) return nil (if I recall correctly).
Posted by Kevin Olbrich (Guest)
on 2006-07-24 15:03
(Received via mailing list)
On Monday, July 24, 2006, at 9:49 AM, Yehuda Katz wrote:
>crudely) for me.
>    end
>    def [](field)
>Object.const_get(self) return nil (if I recall correctly).
>
>--
>Posted via http://www.ruby-forum.com/.
>_______________________________________________
>Rails mailing list
>Rails@lists.rubyonrails.org
>http://lists.rubyonrails.org/mailman/listinfo/rails

Can't you already do this?

class Item < AR:Base
  has_many :widgets
  delegate :thingees, :widgets

  def contents
    self.thingees  # returns self.widgets.thingees
  end
end



_Kevin
www.sciwerks.com
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.