I'm a newbie programmer, been doing shell scripting for years but have recently taken on OOP programming using Ruby and am creating a Rails application.
I'm having a hard time getting my head wrapped around how to use my defined model relationships.
I've tried se开发者_JS百科arching Google, but all I can come up with are basically cheat sheets for what has_many, belongs_to, etc all mean. This stuff is easy to define & understand, especially since I've done a lot of work directly with SQL.
What I don't understand is how to actually used those defined relationships.
In my case I have 3 models: Locations Hosts Services
Relationships (not actual code, just for shortening it):
Services
belongs_to :hosts
Hosts
has_many :services
belongs_to :locations
Locations
has_many :hosts
In this case I want to be able to display a column from Locations while working with Services. In SQL this is a simple join, but I want to do it the Rails/Ruby way, and also not use SQL in my code or redefine my joins.
For what I know you should get used to use singular names for your models,so:
Service
belongs_to :host
Host
has_many :services
belongs_to :location
Location
has_many :hosts
Notice that now the relationships actually make sense: A host has_many serviceS, a service belongs_to a host and a location has_many hosts
Now try on the rails console :
service = Service.create(:name => 'ServiceName')#assuming you only have that field and the host_id of course
service.host# right after creation will return an empty array...so create a host
host = Host.create(:name => 'HostName')#assuming you only have that field and the id of course
#if both were saved to db
host.services << service
#or
service.host << host #should work for you
you can then call
service.host.name
service.host.id # or any other column you have there
You could define a has_many through on Locations.
Locations
has_many :hosts
has_many :services, :through => :hosts
Hosts
belongs_to :location
has_many :services
Services
belongs_to :host
has_one :location, :through => :host #This relationship is optional
Then you could access the services by:
Location.first.services
This will generate this query:
SELECT "services".* FROM "services" INNER JOIN "hosts" ON "services".host_id = "hosts".id WHERE (("hosts".location_id = 1))
...which will gather up all of the services for a given location.
EDIT: I realize that you want the relationship from the other end. To do that, you can access the location from a service by doing service.host.location since each service belongs to one host and each host belongs to one location. You can also add the optional relationship above, so you could just type service.location.column_name.
精彩评论