I am new to stackoverflow, so my apologies if this is formatted poorly.
In my current project I have a model Driver, which has many trips. Those trips have many mileages, backhauls, picks, drops and hours. When I create a new trip, i want to be able to associate it to the driver, but I also want to be able to add the mileages, backhauls, picks and drops and hours on the same page. I am unsure how to structure my routes for this. I have been successful in creating a trip for a driver without adding on the additional models to the trip but from there I am stumped. I have only created the mileage model/controller so far for what needs to be associated with the trip. Any nudge in the right direction would be greatly appreciated.
Driver Model
class Driver < ApplicationRecord
has_many :trips
end
Trip Model
class Trip < ApplicationRecord
belongs_to :driver
has_many :mileages
accepts_nested_attributes_for :mileages
default_scope {order(date: :asc)}
validates :total, presence: true
validates :date, presence: true
validates_uniqueness_of :trip_number, :allow_nil => true, :allow_blank =>
true
end
Mileage Model
class Mileage < ApplicationRecord
belongs_to :trip
end
Trips controller
def index
@trips = Trip.all
end
def show
end
def new
@driver = Driver.find(params[:driver_id])
@trip = Trip.new
end
def edit
end
def create
@driver = Driver.find(params[:driver_id])
@trip = Trip.new(trip_params)
@driver.trips.create(trip_params)
respond_to do |format|
if @driver.trips.create(trip_params)
flash[:notice] = "Trip successfully created"
redirect_to new_driver_trip_path(@driver)
else
flash[:warning] = "Unable to create trip"
redirect_to new_driver_trip_path(@driver)
end
end
private
def set_trip
@trip = Trip.find(params[:id])
end
def trip_params
params.require(:trip).permit(:trip_number, :date, :driver_id, :total)
end
end
Mileage Controller
def new
@mileage = Mileage.new
end
def create
@mileage.create(mileage_params)
end
private
def mileage_params
params.require(:mileage).permit(:miles, :rate, :total)
end
end
end
Driver Controller
def index
@drivers = Driver.all
end
def show
end
def new
@driver = Driver.new
end
def edit
end
def create
@driver = Driver.new(driver_params)
respond_to do |format|
if @driver.save
format.html { redirect_to @driver, notice: 'Driver was
successfully created.' }
format.json { render :show, status: :created, location: @driver }
else
format.html { render :new }
format.json { render json: @driver.errors, status:
:unprocessable_entity }
end
end
end
private
def set_driver
@driver = Driver.find(params[:id])
end
def driver_params
params.require(:driver).permit(:first_name, :last_name, :email, :unit)
end
end
If you want to create nested models on the same page. i.e. milages within trip page using accepts_nested_attributes_for, You can use cocoon gem.
https://github.com/nathanvda/cocoon
Drifting Ruby has a video that shows the process in detail that is easy to follow. https://www.youtube.com/watch?v=56xjUOAAZY8
You can do it manually as well but it will require a little bit more work. With cocoon you will do have a Driver Controller and Trip controller but you don't need a Milage controller since it is handled with nested_attributes via Trip Controller.
If you want to do it manually, you will need a bit of JavaScript. You can follow Ryan Bates RailsCast on this topic. railscasts.com/episodes/196-nested-model-form-revised