我希望如果用户订购了一顿饭,他可以与餐食供应商交谈......反之亦然...... 用户也可以提供膳食和订餐,例如在空中bnb,您可以是客人或主人(或两者)
Exemples:
会话/ index.html.erb
<% @users.each do |user| %>
<%= link_to user.full_name , conversations_path(user_id: user), remote: true, method: :post %>
<% end %>
user.rb (我对此模型有疑问......)
has_many :meals #Meals that the user offers
has_many :received_orders, class_name: "Order" #The user receive an order
has_many :placed_orders, through: :meals, class_name: "Order" #The user order a meal
has_many :prepared_orders, through: :received_orders, class_name: "Meal", source: :meal #The user has prepared the order
####maybe this way below....TODO
# has_many :meals
# has_many :orders_as_a_customer, class_name: "Order"# same as: has_many :orders
# has_many :orders_as_a_seller, through: :orders_as_a_customer, class_name: "Meal", source: :meal
# has_many :orders, through: :meals
order.rb
class Order < ApplicationRecord
before_save :calculate_price
belongs_to :user
belongs_to :meal
has_many :notifications, as: :topic
monetize :amount_cents, as: :amount
def payment
self.payment_status = true
self.save
end
def calculate_price
self.amount = (self.quantity * meal.price)
end
end
我已按照此tutorial创建了我的聊天,我打赌可以调整到我的应用程序...
conversation.rb
class Conversation < ApplicationRecord
has_many :messages, dependent: :destroy
belongs_to :sender, foreign_key: :sender_id, class_name: "User"
belongs_to :recipient, foreign_key: :recipient_id, class_name: "User"
validates :sender_id, uniqueness: { scope: :recipient_id }
scope :between, -> (sender_id, recipient_id) do
where(sender_id: sender_id, recipient_id: recipient_id).or(
where(sender_id: recipient_id, recipient_id: sender_id)
)
end
def self.get(sender_id, recipient_id)
conversation = between(sender_id, recipient_id).first
return conversation if conversation.present?
create(sender_id: sender_id, recipient_id: recipient_id)
end
def opposed_user(user)
user == recipient ? sender : recipient
end
end
conversations_controller.rb
class ConversationsController < ApplicationController
def create
@conversation = Conversation.get(current_user.id, params[:user_id])
add_to_conversations unless conversated?
respond_to do |format|
format.js
end
end
def index
session[:conversations] ||= []
@users = User.all.where.not(id: current_user)
@conversations = Conversation.includes(:recipient, :messages).find(session[:conversations])
end
def close
@conversation = Conversation.find(params[:id])
session[:conversations].delete(@conversation.id)
respond_to do |format|
format.js
end
end
private
def add_to_conversations
session[:conversations] ||= []
session[:conversations] << @conversation.id
end
def conversated?
session[:conversations].include?(@conversation.id)
end
end
我的实际 schema.rb
ActiveRecord::Schema.define(version: 20170629192651) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "attachinary_files", force: :cascade do |t|
t.string "attachinariable_type"
t.integer "attachinariable_id"
t.string "scope"
t.string "public_id"
t.string "version"
t.integer "width"
t.integer "height"
t.string "format"
t.string "resource_type"
t.datetime "created_at"
t.datetime "updated_at"
t.index ["attachinariable_type", "attachinariable_id", "scope"], name: "by_scoped_parent", using: :btree
end
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "conversations", force: :cascade do |t|
t.integer "recipient_id"
t.integer "sender_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "order_id"
t.index ["order_id"], name: "index_conversations_on_order_id", using: :btree
t.index ["recipient_id", "sender_id"], name: "index_conversations_on_recipient_id_and_sender_id", unique: true, using: :btree
end
create_table "ingredients", force: :cascade do |t|
t.string "name"
t.integer "meal_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["meal_id"], name: "index_ingredients_on_meal_id", using: :btree
end
create_table "meals", force: :cascade do |t|
t.string "menu_name"
t.integer "portion"
t.date "availability"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.integer "category_id"
t.string "images"
t.string "location"
t.float "latitude"
t.float "longitude"
t.integer "price"
t.index ["user_id"], name: "index_meals_on_user_id", using: :btree
end
create_table "messages", force: :cascade do |t|
t.text "body"
t.integer "user_id"
t.integer "conversation_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["conversation_id"], name: "index_messages_on_conversation_id", using: :btree
t.index ["user_id"], name: "index_messages_on_user_id", using: :btree
end
create_table "notifications", force: :cascade do |t|
t.boolean "read", default: false
t.string "content"
t.integer "user_id"
t.string "topic_type"
t.integer "topic_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "order_id"
t.index ["order_id"], name: "index_notifications_on_order_id", using: :btree
t.index ["topic_type", "topic_id"], name: "index_notifications_on_topic_type_and_topic_id", using: :btree
t.index ["user_id"], name: "index_notifications_on_user_id", using: :btree
end
create_table "orders", force: :cascade do |t|
t.text "message"
t.boolean "payment_status", default: false
t.integer "quantity"
t.integer "user_id"
t.integer "meal_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "amount_cents", default: 0, null: false
t.json "payment"
t.index ["meal_id"], name: "index_orders_on_meal_id", using: :btree
t.index ["user_id"], name: "index_orders_on_user_id", using: :btree
end
create_table "reviews", force: :cascade do |t|
t.integer "rating"
t.text "comment"
t.integer "meal_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["meal_id"], name: "index_reviews_on_meal_id", using: :btree
t.index ["user_id"], name: "index_reviews_on_user_id", using: :btree
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "provider"
t.string "uid"
t.string "facebook_picture_url"
t.string "first_name"
t.string "last_name"
t.string "token"
t.datetime "token_expiry"
t.string "nickname"
t.string "avatar"
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
add_foreign_key "conversations", "orders"
add_foreign_key "meals", "users"
add_foreign_key "messages", "conversations"
add_foreign_key "messages", "users"
add_foreign_key "notifications", "orders"
add_foreign_key "notifications", "users"
add_foreign_key "orders", "meals"
add_foreign_key "orders", "users"
add_foreign_key "reviews", "meals"
add_foreign_key "reviews", "users"
end
答案 0 :(得分:0)
从评论中得出结论,您需要拥有不同的模型。以下是对我有用的内容:
class User < ApplicationRecord
has_many :meals
has_many :orders
has_many :sent_messages, :class => 'ChatMessage', :foreign_key => 'sender_id'
has_many :received_messages, :class => 'ChatMessage', :foreign_key => 'receiver_id'
end
class Meal < ApplicationRecord
belongs_to :user
belongs_to :order_item
end
class Order < ApplicationRecord
belongs_to :user
has_many :order_items
end
class OrderItem < ApplicationRecord
belongs_to :order
has_one :meal
end
class ChatMessage < ApplicationRecord
belongs_to :sender, :class => 'User'
belongs_to :receiver, :class => 'User'
end