소스 검색

Make it possible to add users to an existing conversation

Frans Bergman 7 년 전
부모
커밋
dd5bf79b4a

+ 1 - 0
Gemfile

@@ -33,6 +33,7 @@ gem 'jquery-rails', '~> 4.3.1'
 gem "font-awesome-rails"
 # Bootstrap Forms
 gem 'bootstrap_form', '~> 2.7.0'
+gem 'select2-rails', '~> 4.0.3'
 # Use Redis adapter to run Action Cable in production
 # gem 'redis', '~> 3.0'
 # Use ActiveModel has_secure_password

+ 3 - 0
Gemfile.lock

@@ -161,6 +161,8 @@ GEM
       sprockets (>= 2.8, < 4.0)
       sprockets-rails (>= 2.0, < 4.0)
       tilt (>= 1.1, < 3)
+    select2-rails (4.0.3)
+      thor (~> 0.14)
     selenium-webdriver (3.8.0)
       childprocess (~> 0.5)
       rubyzip (~> 1.0)
@@ -219,6 +221,7 @@ DEPENDENCIES
   rails (~> 5.1.4)
   rails-controller-testing
   sass-rails (~> 5.0)
+  select2-rails (~> 4.0.3)
   selenium-webdriver
   spring
   spring-watcher-listen (~> 2.0.0)

+ 1 - 0
app/assets/javascripts/application.js

@@ -14,4 +14,5 @@
 //= require turbolinks
 //= require jquery
 //= require bootstrap-sprockets
+//= require select2
 //= require_tree .

+ 3 - 0
app/assets/javascripts/conversation_participations.coffee

@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/

+ 2 - 0
app/assets/stylesheets/application.css

@@ -11,6 +11,8 @@
  * It is generally better to create a new file per style scope.
  *
  *= require rails_bootstrap_forms
+ *= require select2
+ *= require select2-bootstrap
  *= require_tree .
  *= require_self
  */

+ 3 - 0
app/assets/stylesheets/conversation_participations.scss

@@ -0,0 +1,3 @@
+// Place all the styles related to the ConversationParticipations controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/

+ 31 - 0
app/controllers/conversation_participations_controller.rb

@@ -0,0 +1,31 @@
+class ConversationParticipationsController < ApplicationController
+
+  before_action :set_conversation
+  before_action :check_permissions, only: :create
+
+  def create
+    @participation = ConversationParticipation.create(participation_params)
+    if @participation.save
+      flash[:success] = "Added user to conversation"
+    end
+    redirect_to @conversation
+  end
+
+  private
+    def participation_params
+      params.require(:conversation_participation).permit(:conversation_id,
+                                                         :user_id)
+    end
+
+    def set_conversation
+      @conversation = Conversation.find(participation_params[:conversation_id])
+    end
+
+    def check_permissions
+      unless current_user.conversations.include? @conversation
+        flash[:danger] = "You are not part of this conversation"
+        redirect_to root_path
+      end
+    end
+
+end

+ 2 - 0
app/helpers/conversation_participations_helper.rb

@@ -0,0 +1,2 @@
+module ConversationParticipationsHelper
+end

+ 8 - 0
app/views/conversation_participations/_form.html.erb

@@ -0,0 +1,8 @@
+<%= bootstrap_form_for(@conversation.conversation_participations.build) do |f| %>
+  <%= render 'shared/error_messages', object: f.object %>
+  <%= f.hidden_field :conversation_id, value: @conversation.id %>
+
+  <%= f.select :user_id, options_for_select(User.where.not(id: @conversation.users.map(&:id)).map{ |user| [user.name, user.id] }) %>
+
+  <%= f.submit "Add user", class: "btn btn-primary" %>
+<% end %>

+ 8 - 0
app/views/conversations/show.html.erb

@@ -21,5 +21,13 @@
         </li>
       <% end %>
     </ul>
+    <h3>Add user to conversation</h3>
+    <%= render 'conversation_participations/form' %>
   </div>
 </div>
+
+<script>
+  $(document).ready(function() {
+    $('#conversation_participation_user_id').select2();
+  });
+</script>

+ 1 - 0
config/routes.rb

@@ -10,5 +10,6 @@ Rails.application.routes.draw do
 
   resources :users
   resources :conversations
+  resources :conversation_participations
   resources :messages
 end

+ 31 - 0
test/controllers/conversation_participations_controller_test.rb

@@ -0,0 +1,31 @@
+require 'test_helper'
+
+class ConversationParticipationsControllerTest < ActionDispatch::IntegrationTest
+  def setup
+    @user = users(:daniel)
+    @other_user = users(:jane)
+    @conversation = conversations(:one)
+    @unallowed_conversation = conversations(:two)
+    log_in_as @user
+  end
+
+  test "should create valid conversation participation" do
+    get conversation_path @conversation
+    assert_difference 'ConversationParticipation.all.count', 1 do
+      post conversation_participations_path,
+        params: { conversation_participation: {
+          conversation_id: @conversation.id, user_id: @other_user.id
+        } }
+    end
+    assert_redirected_to conversation_path @conversation
+  end
+
+  test "should not create invalid conversation participation" do
+    assert_no_difference 'ConversationParticipation.all.count' do
+      post conversation_participations_path,
+        params: { conversation_participation: {
+          conversation_id: @unallowed_conversation.id, user_id: @other_user.id
+        } }
+    end
+  end
+end

+ 7 - 0
test/fixtures/users.yml

@@ -13,3 +13,10 @@ ben:
   email: ben.jones@example.com
   password_digest: <%= User.digest('password') %>
   birth_date: <%= 29.years.ago %>
+
+jane:
+  login: jane_5678
+  name: Jane Doe
+  email: jane.doe@example.com
+  password_digest: <%= User.digest('password') %>
+  birth_date: <%= 30.years.ago %>