Reputation: 11751
I'm new to Ruby On Rails and followed the RoR guide to create a blog: http://guides.rubyonrails.org/getting_started.html
According to different articles I should avoid having resources nested more than one level. (http://guides.rubyonrails.org/routing.html#nested-resources 2.7.1)
They reference to this article about best practices: http://weblog.jamisbuck.org/2007/2/5/nesting-resources
Without having nested resources in my project right now, how do I have to create the form properly to set the reference properly?
My routes.rb file
Monitoring::Application.routes.draw do
resources :companies
resources :jobs
root :to => 'companies#index'
company.rb
class Company < ActiveRecord::Base
attr_accessible :name
has_many :jobs, :dependent => :destroy
end
job.rb
class Job < ActiveRecord::Base
belongs_to :company
attr_accessible :interval, :name
end
A job belongs to one company.
_form.html.erb inside the jobs view folder
<%= form_for @job, :html => { :class => 'form-horizontal' } do |f| %>
<div class="control-group">
<%= f.label :name, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :name, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :interval, :class => 'control-label' %>
<div class="controls">
<%= f.number_field :interval, :class => 'number_field' %>
</div>
</div>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
jobs_path, :class => 'btn' %>
</div>
<% end %>
To actually create the job with a reference to its company I tried the following code
def new
@company = Company.find(params[:company])
@job = @company.jobs.build
respond_to do |format|
format.html # new.html.erb
end
end
Is there any open source example code that demonstrates creating new objects without nested objects?
Right now, the company parameter is not properly set when creating a new job, which means I can't fetch the company to create the job from there. How do I create a new job with the correct reference to its company?
Upvotes: 2
Views: 227
Reputation: 3507
without doing nested routes you should just drop a hidden input in the form with the company id.
<%= f.hidden_field :company_id, value: @company.id %>
However, this is obviously easily hackable by the client. If permissions are a concern, then you should just set it server side:
@job = Job.new(company_id: @company.id)
and if you need to do mass assignment:
@job = Job.new(params[:job].merge(company_id: @company.id))
#or do it after the fact
@job = Job.new(params[:job])
@job.company_id = @company.id
As an aside, I see no inherent problem with nesting resources 2 or even 3 levels deep. Its really a case-by-case kind of thing. For me, the two major considerations when deciding levels of nesting, are 1) how will the urls be accessed 2) what does my object graph look like; will I always have the parent model(s) around when dealing with links and forms
Upvotes: 3