瀏覽代碼

Add models for messaging feature

Frans Bergman 7 年之前
父節點
當前提交
94467ae337

+ 10 - 0
app/models/conversation.rb

@@ -0,0 +1,10 @@
+class Conversation < ApplicationRecord
+  validates :name, presence: true, length: { maximum: 255 }
+
+  has_many :messages, dependent: :destroy
+  accepts_nested_attributes_for :messages
+
+  has_many :conversation_participations, dependent: :destroy
+
+  has_many :users, through: :conversation_participations
+end

+ 6 - 0
app/models/conversation_participation.rb

@@ -0,0 +1,6 @@
+class ConversationParticipation < ApplicationRecord
+  belongs_to :user
+  belongs_to :conversation
+  validates :user_id, presence: true
+  validates :conversation_id, presence: true
+end

+ 8 - 0
app/models/message.rb

@@ -0,0 +1,8 @@
+class Message < ApplicationRecord
+  validates :content, presence: true
+
+  default_scope -> { order(created_at: :asc) }
+
+  belongs_to :user
+  belongs_to :conversation
+end

+ 4 - 0
app/models/user.rb

@@ -29,6 +29,10 @@ class User < ApplicationRecord
   mount_uploader :picture, PictureUploader
   validate :picture_size
 
+  has_many :messages
+  has_many :conversation_participations, dependent: :destroy
+  has_many :conversations, through: :conversation_participations
+
   # Returns the hash digest of the given string.
   def User.digest(string)
     cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :

+ 12 - 0
db/migrate/20171222170246_create_messages.rb

@@ -0,0 +1,12 @@
+class CreateMessages < ActiveRecord::Migration[5.1]
+  def change
+    create_table :messages do |t|
+      t.belongs_to :user, foreign_key: true
+      t.belongs_to :conversation, foreign_key: true
+      t.text :content
+
+      t.timestamps
+    end
+    add_index :messages, [:conversation_id, :created_at]
+  end
+end

+ 9 - 0
db/migrate/20171222170826_create_conversations.rb

@@ -0,0 +1,9 @@
+class CreateConversations < ActiveRecord::Migration[5.1]
+  def change
+    create_table :conversations do |t|
+      t.string :name
+
+      t.timestamps
+    end
+  end
+end

+ 14 - 0
db/migrate/20171222171109_create_conversation_participations.rb

@@ -0,0 +1,14 @@
+class CreateConversationParticipations < ActiveRecord::Migration[5.1]
+  def change
+    create_table :conversation_participations do |t|
+      t.integer :user_id
+      t.integer :conversation_id
+      t.datetime :viewed_at, null: false
+
+      t.timestamps
+    end
+    add_index :conversation_participations,
+              [:user_id, :conversation_id], unique: true,
+              name: :index_participation_user_conversation
+  end
+end

+ 27 - 1
db/schema.rb

@@ -10,7 +10,33 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20171222122058) do
+ActiveRecord::Schema.define(version: 20171222171109) do
+
+  create_table "conversation_participations", force: :cascade do |t|
+    t.integer "user_id"
+    t.integer "conversation_id"
+    t.datetime "viewed_at"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["user_id", "conversation_id"], name: "index_participation_user_conversation", unique: true
+  end
+
+  create_table "conversations", force: :cascade do |t|
+    t.string "name"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+  end
+
+  create_table "messages", force: :cascade do |t|
+    t.integer "user_id"
+    t.integer "conversation_id"
+    t.text "content"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["conversation_id", "created_at"], name: "index_messages_on_conversation_id_and_created_at"
+    t.index ["conversation_id"], name: "index_messages_on_conversation_id"
+    t.index ["user_id"], name: "index_messages_on_user_id"
+  end
 
   create_table "users", force: :cascade do |t|
     t.string "name"

+ 10 - 1
db/seeds.rb

@@ -6,7 +6,7 @@
 #   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
 #   Character.create(name: 'Luke', movie: movies.first)
 
-User.create!(name:  "Example User",
+user = User.create!(name:  "Example User",
              login: "example",
              email: "example@example.com",
              password:              "foobar",
@@ -30,3 +30,12 @@ User.create!(name:  "Example User",
               birth_date: birth_date,
               phone:      phone)
 end
+
+conversation = Conversation.create!(name: "Important conversation")
+
+ConversationParticipation.create!(conversation: conversation, user: user)
+
+10.times do |n|
+  content = Faker::Lorem.sentence(10)
+  Message.create!(user: user, conversation: conversation, content: content)
+end

+ 11 - 0
test/fixtures/conversation_participations.yml

@@ -0,0 +1,11 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  user: daniel
+  conversation: one
+  viewed_at: 2017-12-22 18:11:09
+
+two:
+  user: ben
+  conversation: one
+  viewed_at: 2017-12-22 18:11:09

+ 7 - 0
test/fixtures/conversations.yml

@@ -0,0 +1,7 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  name: Conversation 1
+
+two:
+  name: Conversation 2

+ 11 - 0
test/fixtures/messages.yml

@@ -0,0 +1,11 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  user: daniel
+  conversation: one
+  content: First
+
+two:
+  user: daniel
+  conversation: one
+  content: Second

+ 22 - 0
test/models/conversation_participation_test.rb

@@ -0,0 +1,22 @@
+require 'test_helper'
+
+class ConversationParticipationTest < ActiveSupport::TestCase
+  def setup
+    @participation = ConversationParticipation.new(user_id: users(:daniel).id,
+                                     conversation_id: conversations(:two).id)
+  end
+
+  test "should be valid" do
+    assert @participation.valid?
+  end
+
+  test "should require a user_id" do
+    @participation.user_id = nil
+    assert_not @participation.valid?
+  end
+
+  test "should require a conversation_id" do
+    @participation.conversation_id = nil
+    assert_not @participation.valid?
+  end
+end

+ 16 - 0
test/models/conversation_test.rb

@@ -0,0 +1,16 @@
+require 'test_helper'
+
+class ConversationTest < ActiveSupport::TestCase
+  def setup
+    @conversation = Conversation.new(name: "Conversation")
+  end
+
+  test "should be valid" do
+    assert @conversation.valid?
+  end
+
+  test "name should be present" do
+    @conversation.name = "      "
+    assert_not @conversation.valid?
+  end
+end

+ 22 - 0
test/models/message_test.rb

@@ -0,0 +1,22 @@
+require 'test_helper'
+
+class MessageTest < ActiveSupport::TestCase
+  def setup
+    @message = messages(:one)
+  end
+
+  test "should be valid" do
+    assert @message.valid?
+  end
+
+  test "content should be present" do
+    @message.content = "      "
+    assert_not @message.valid?
+  end
+
+  test "should destroy messages on conversation destroy" do
+    assert_difference "Message.all.count", -2 do
+      conversations(:one).destroy
+    end
+  end
+end