Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zero or many association in ActiveRecord

I am new to rails and writing an application which has two models job and sub_job In my application job can have either zero , one or many sub_jobs

The has_many association will create one to many relationship for jobs.

I have written the following in the respective models

#app/models/job.rb
class Job < ActiveRecord::Base
   has_many :sub_jobs
end

#app/models/sub_job.rb
class SubJob < ActiveRecord::Base
   belongs_to :job
end

Now it means a job can have multiple sub_jobs but my question is:

Will has_many association handle the case when there is no subjob for a particular job ?

like image 874
Sunil Sharma Avatar asked Sep 02 '25 13:09

Sunil Sharma


2 Answers

yes, absolutely. If you wanted to ensure that there was at least one job, you'd put in a validation in the Job model.

validates :sub_jobs, :presence => true

But in your case you don't need that, so you don't put it in.

Any Job records without SubJob records associated will simply return an empty array...

p my_job.sub_jobs
=> []
like image 77
SteveTurczyn Avatar answered Sep 05 '25 06:09

SteveTurczyn


Will has_many association handle the case when there is no subjob for a particular job ?

Short answer: yes

--

Long answer:

Rails isn't a magic wizard, it's simply a layer of abstraction for dealing with requests & relational databases.

This means that if you have a has_many association, what you're really telling Rails is to use SQL to look up any references to the original model in the associated table.

enter image description here

You can read more here.

It does not mean you have to have "many" instances of an associated record, or even that you have to have any at all. It simply means Rails will look up any associated records with the corresponding foreign_key in the related table.

For example...

#app/models/job.rb
class Job < ActiveRecord::Base
    # columns id | title | description | created_at | updated_at
    has_many :sub_jobs
end

#app/models/sub_job.rb
class SubJob < ActiveRecord::Base
    # columns id | job_id | title | etc 
    belongs_to :job
end

The job_id column is the foreign_key, thus is what Rails will use to look up any corresponding records.

You can then do this:

#app/controllers/jobs_controller.rb
class JobsController < ActionController::Base
   def show
      @job = Job.find params[:id]
   end
end

#app/views/jobs/show.html.erb
<% if @job.sub_jobs.any? %>
   <% @job.sub_jobs.each do |sub| %>
       <%= sub.title %>
   <% end %>
<% end %>

If no associated sub_jobs exist, it will just not put anything out.

like image 31
Richard Peck Avatar answered Sep 05 '25 06:09

Richard Peck