Rails 3.1 Different Views for One Model

2019-07-20 11:03发布

问题:

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     

回答1:

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.



回答2:

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!