How to handle multiple orders for an user

2019-08-13 12:23发布

问题:

In my view there is a query like this ..

<%= CaricatureType.find_by(id: StudioOrder.find_by(user_id: spree_current_user.id).style_id).name %>

The schema for studio_orders and caricature_types is as follows

create_table "studio_orders", force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "occasion_id"
    t.integer  "style_id"
    t.integer  "number_of_people"
    t.string   "artwork_size"
    t.integer  "package_id"
    t.text     "instructions"
    t.datetime "created_at",         null: false
    t.datetime "updated_at",         null: false
    t.float    "initial_price"
    t.float    "final_price"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
    t.json     "avatars"
    t.integer  "address_id"
  end


create_table "caricature_types", force: :cascade do |t|
    t.string   "name"
    t.text     "description"
    t.float    "price"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

Now the question is, the query in the view I have posted above comes in order_summary screen, and the query simply outputs the name of the style he has choosen. Now the thing is, technically there can be many rows in the studio_orders with the same user id. But how to display the current style the user has choosen in the order_summary screen.

回答1:

It's bad practice to put any ActiveRecord declarations in your view. All of that should be handled by the controller:

#app/controllers/your_controller.rb
class YourController < ApplicationController
  def show
    @types = CaricatureType.find_by(id: StudioOrder.find_by(user_id: spree_current_user.id).style_id).name %> 
  end
end

This has two benefits:

  1. All your logic is kept in one place
  2. ActiveRecord will reuse the data if it's called multiple times through an @instance_variable

For your specific issue,

But how to display the current style the user has choosen in the order_summary screen

This is for you to determine.

Ideally, you'd want to put a current column in your studio_orders table. Assigning the type boolean to this column will allow you to use the following:

@current_type = CaricatureType.find_by id: spree_current_user.studio_orders.style_id, current: true

Rails might value convention over configuration - but you're free to construct your schema / models as you see fit. This includes setting a current column if you need it.