I have an application where I have a Shipment model. I have created a view that allows me to create shipments and view shipments in a table based layout. Everything lies in the index.html.erb because all actions are done through ajax.
When a shipment is created, the status is "OPEN" by default. Later on when a bill of lading is printed, the status will change to "PRINTED".
My goal is to create another view that lists only the open shipments allowing an operator to print the bill of lading using a separate form. My question is how does rails handle the rendering of multiple forms and views for one model? Should I use a separate controller/view to handle the action/views associated with printing, or should I use two models for ex. Shipment and OpenShipment? I'm having a hard time finding documentation that explains this issue.
Listed below is my schema for this Model as well as a directory structure for the current view. Hope this helps explain the issue.
Shipment Model
t.string :item_code
t.string :status
t.string :bill_of_lading
t.integer :qty_shipped
t.datetime :ship_date
t.datetime :delivery_date
View Directory Structure
views
shipments
index.html.erb
_shipment.html.erb
_shipment_table.html.erb
_form.html.erb
_edit_form.html.erb
create.js.coffee
edit.js.coffee
update.js.coffee
destroy.js.coffee
As I see, you will be showing the same thing twice. You could solve this in two ways: either you add a parameter, and keep the same controller action, or you add a new controller action (which possibly makes a cleaner url --depends on your preference).
First, you define a scope
on Shipment
:
class Shipment
scope :open, lambda { where(:status => 'open')
end
This will allow to write something like:
Shipment.open
and this will give you all the open shipments.
So you could define a new controller action as follows
def open_shipments
@shipments = Shipment.open
render :index
end
This will retrieve the open shipments, and then render the same view as for index.
To make it even cleaner, you could make the state a parameter in your url.
In your config/routes.rb
write
get 'shipments/status/:status', :as => 'shipments#index'
And then you will have to edit your index
action as follows:
def index
if params[:status]
@shipments = Shipment.where(:status => params[:status])
else
@shipments = Shipment.all
end
end
And you can then just visit the url shipments/status/open
which will give the open shipments, and likewise shipments/status/printed
will give all the printed shipments.
But the url shipments?status=open
will give you the same result (without any changes to the routes necessary). Depends on your flavour.
Hope this helps.
Create a new action in the controller called open_shipments and a new view file called open_shipments.html.erb. Add a new route to your routes table, and create a link in some view to link the new route.
In the controller action, access the model objects into instance variables and display from those instance variables in the view.
Good luck!