Frans Bergman vor 7 Jahren
Ursprung
Commit
0015a64ddd

+ 3 - 0
app/assets/javascripts/news_posts.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/

+ 10 - 0
app/assets/stylesheets/news_posts.scss

@@ -0,0 +1,10 @@
+// Place all the styles related to the NewsPosts controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
+
+.news-post {
+  padding: 10px;
+  border-radius: 10px;
+  background-color: #f5f5f5;
+  margin-bottom: 10px;
+}

+ 74 - 0
app/controllers/news_posts_controller.rb

@@ -0,0 +1,74 @@
+class NewsPostsController < ApplicationController
+  before_action :set_news_post, only: [:show, :edit, :update, :destroy]
+  before_action :check_can_edit, only: [:edit, :update, :destroy]
+  before_action :check_correct_user, only: [:edit, :update]
+
+  # GET /news_posts/1
+  # GET /news_posts/1.json
+  def show
+  end
+
+  # GET /news_posts/1/edit
+  def edit
+  end
+
+  # POST /news_posts
+  # POST /news_posts.json
+  def create
+    @news_post = NewsPost.new(news_post_params)
+    @news_post.user = current_user
+
+    respond_to do |format|
+      if @news_post.save
+        format.html { redirect_to @news_post.news_feed, notice: 'News post was successfully created.' }
+        format.json { render :show, status: :created, location: @news_post }
+      else
+        format.html { render :new }
+        format.json { render json: @news_post.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+
+  # PATCH/PUT /news_posts/1
+  # PATCH/PUT /news_posts/1.json
+  def update
+    respond_to do |format|
+      if @news_post.update(news_post_params)
+        format.html { redirect_to @news_post, notice: 'News post was successfully updated.' }
+        format.json { render :show, status: :ok, location: @news_post }
+      else
+        format.html { render :edit }
+        format.json { render json: @news_post.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+
+  # DELETE /news_posts/1
+  # DELETE /news_posts/1.json
+  def destroy
+    @news_post.destroy
+    respond_to do |format|
+      format.html { redirect_to news_posts_url, notice: 'News post was successfully destroyed.' }
+      format.json { head :no_content }
+    end
+  end
+
+  private
+    # Use callbacks to share common setup or constraints between actions.
+    def set_news_post
+      @news_post = NewsPost.find(params[:id])
+    end
+
+    # Never trust parameters from the scary internet, only allow the white list through.
+    def news_post_params
+      params.require(:news_post).permit(:name, :content, :news_feed_id, :news_feed_type)
+    end
+
+    def check_can_edit
+      redirect_to root_url unless @news_post.news_feed.can_post_news?(current_user)
+    end
+
+    def check_correct_user
+      redirect_to root_url unless @news_post.user == current_user
+    end
+end

+ 2 - 0
app/helpers/news_posts_helper.rb

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

+ 6 - 0
app/models/course.rb

@@ -24,6 +24,12 @@ class Course < ApplicationRecord
     self.users.merge(CourseParticipation.teachers).include?(user)
   end
 
+  has_many :news_posts, as: :news_feed
+
+  def can_post_news?(user)
+    self.users.merge(CourseParticipation.teachers).include?(user)
+  end
+
   private
     def date_order
       if ends_on < starts_on

+ 19 - 0
app/models/news_post.rb

@@ -0,0 +1,19 @@
+class NewsPost < ApplicationRecord
+  belongs_to :user
+  validates :user_id, presence: true
+  belongs_to :news_feed, polymorphic: true
+  validates :news_feed_id, presence: true
+
+  validates :name, presence: true, length: { maximum: 255 }
+
+  validate :user_permission
+
+  default_scope { order(created_at: :desc) }
+
+  private
+    def user_permission
+      unless self.news_feed.can_post_news?(self.user)
+        errors.add(:user, "does not have permission to post in this feed")
+      end
+    end
+end

+ 6 - 0
app/models/school.rb

@@ -18,4 +18,10 @@ class School < ApplicationRecord
   def can_upload_files?(user)
     self.administrators.include?(user)
   end
+
+  has_many :news_posts, as: :news_feed
+
+  def can_post_news?(user)
+    self.administrators.include?(user)
+  end
 end

+ 8 - 3
app/views/courses/show.html.erb

@@ -5,11 +5,16 @@
   </div>
 </div>
 <div class="row">
-  <div class="col-md-6">
+  <div class="col-lg-4 col-md-6">
+    <%= render partial: 'news_posts/news_feed', locals: { news_feed: @course } %>
+  </div>
+  <div class="col-lg-4 col-md-6">
     <%= render partial: 'participants_panel' %>
-    <%= render partial: 'lectures_panel' %>
   </div>
-  <div class="col-md-6">
+  <div class="col-lg-4 col-md-6">
     <%= render partial: 'data_files/file_panel', locals: { repository: @course } %>
   </div>
+  <div class="col-lg-8 col-md-6">
+    <%= render partial: 'lectures_panel' %>
+  </div>
 </div>

+ 11 - 0
app/views/news_posts/_form.html.erb

@@ -0,0 +1,11 @@
+<%= bootstrap_form_for(@news_post) do |f| %>
+  <%= render 'shared/error_messages', object: f.object %>
+
+  <%= f.text_field :name, label: 'Title' %>
+  <%= f.text_area :content %>
+
+  <%= f.hidden_field :news_feed_id %>
+  <%= f.hidden_field :news_feed_type %>
+
+  <%= f.submit class: "btn btn-primary" %>
+<% end %>

+ 10 - 0
app/views/news_posts/_news_feed.html.erb

@@ -0,0 +1,10 @@
+<h3>News feed</h3>
+<% for news_post in news_feed.news_posts do %>
+  <%= render news_post %>
+<% end %>
+<% if news_feed.can_post_news?(current_user) %>
+  <h4>New post</h4>
+
+  <% @news_post = news_feed.news_posts.build %>
+  <%= render 'news_posts/form' %>
+<% end %>

+ 9 - 0
app/views/news_posts/_news_post.html.erb

@@ -0,0 +1,9 @@
+<div class="news-post">
+  <h4><%= news_post.name %></h4>
+  <p>
+    <%= format_content(news_post.content) %>
+  </p>
+  <small>
+    <%= news_post.created_at %>
+  </small>
+</div>

+ 2 - 0
app/views/news_posts/_news_post.json.jbuilder

@@ -0,0 +1,2 @@
+json.extract! news_post, :id, :name, :content, :user_id, :news_feed_id, :created_at, :updated_at
+json.url news_post_url(news_post, format: :json)

+ 4 - 0
app/views/news_posts/edit.html.erb

@@ -0,0 +1,4 @@
+<%= provide(:title, "Edit News Post") %>
+<h1>Editing News Post</h1>
+
+<%= render 'form' %>

+ 4 - 0
app/views/news_posts/show.html.erb

@@ -0,0 +1,4 @@
+<%= provide(:title, @news_post.name) %>
+<h1>News Post</h1>
+
+<%= render @news_post %>

+ 1 - 0
app/views/news_posts/show.json.jbuilder

@@ -0,0 +1 @@
+json.partial! "news_posts/news_post", news_post: @news_post

+ 3 - 0
app/views/schools/show.html.erb

@@ -5,6 +5,9 @@
   </div>
 </div>
 <div class="row">
+  <div class="col-md-6">
+    <%= render partial: 'news_posts/news_feed', locals: { news_feed: @school } %>
+  </div>
   <div class="col-md-6">
     <%= render partial: 'data_files/file_panel', locals: { repository: @school } %>
   </div>

+ 1 - 0
config/routes.rb

@@ -1,4 +1,5 @@
 Rails.application.routes.draw do
+  resources :news_posts
   root 'sessions#new'
 
   get '/home', to: 'static_pages#home'

+ 12 - 0
db/migrate/20180407105907_create_news_posts.rb

@@ -0,0 +1,12 @@
+class CreateNewsPosts < ActiveRecord::Migration[5.1]
+  def change
+    create_table :news_posts do |t|
+      t.string :name
+      t.text :content
+      t.belongs_to :user, foreign_key: true
+      t.references :news_feed, index: true, polymorphic: true
+
+      t.timestamps
+    end
+  end
+end

+ 13 - 1
db/schema.rb

@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20180404090939) do
+ActiveRecord::Schema.define(version: 20180407105907) do
 
   create_table "administrations", force: :cascade do |t|
     t.integer "user_id"
@@ -110,6 +110,18 @@ ActiveRecord::Schema.define(version: 20180404090939) do
     t.index ["user_id"], name: "index_messages_on_user_id"
   end
 
+  create_table "news_posts", force: :cascade do |t|
+    t.string "name"
+    t.text "content"
+    t.integer "user_id"
+    t.string "news_feed_type"
+    t.integer "news_feed_id"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["news_feed_type", "news_feed_id"], name: "index_news_posts_on_news_feed_type_and_news_feed_id"
+    t.index ["user_id"], name: "index_news_posts_on_user_id"
+  end
+
   create_table "schools", force: :cascade do |t|
     t.string "name"
     t.datetime "created_at", null: false

+ 7 - 0
db/seeds.rb

@@ -71,3 +71,10 @@ end
   due_at = Faker::Number.between(1, 10).days.since
   Assignment.create(course: course, name: name, description: description, due_at: due_at)
 end
+
+5.times do |n|
+  name = Faker::Lorem.sentence(4)
+  content = Faker::Lorem.paragraph
+  course = Course.find(1)
+  NewsPost.create(user: user, content: content, name: name, news_feed: course)
+end

+ 42 - 0
test/controllers/news_posts_controller_test.rb

@@ -0,0 +1,42 @@
+require 'test_helper'
+
+class NewsPostsControllerTest < ActionDispatch::IntegrationTest
+  setup do
+    @news_post = news_posts(:one)
+    @course = courses(:one)
+    @teacher = users(:daniel)
+    log_in_as @teacher
+  end
+
+  test "should create news_post" do
+    assert_difference('NewsPost.count') do
+      post news_posts_url, params: { news_post: { content: @news_post.content, name: @news_post.name, news_feed_id: @course.id, news_feed_type: 'Course' } }
+    end
+
+    assert_redirected_to @course
+  end
+
+  test "should get show" do
+    get news_post_url(@news_post)
+    assert_response :success
+  end
+
+  test "should get edit" do
+    get edit_news_post_url(@news_post)
+    assert_response :success
+  end
+
+  test "should update news_post" do
+    patch news_post_url(@news_post), params: { news_post: { content: @news_post.content, name: 'New Name' } }
+    assert_equal 'New Name', @news_post.reload.name
+    assert_redirected_to @news_post
+  end
+
+  test "should destroy news_post" do
+    assert_difference('NewsPost.count', -1) do
+      delete news_post_url(@news_post)
+    end
+
+    assert_redirected_to news_posts_url
+  end
+end

+ 7 - 0
test/fixtures/news_posts.yml

@@ -0,0 +1,7 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  name: MyString
+  content: MyText
+  user: daniel
+  news_feed: one (Course)

+ 7 - 0
test/models/news_post_test.rb

@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class NewsPostTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end

+ 9 - 0
test/system/news_posts_test.rb

@@ -0,0 +1,9 @@
+require "application_system_test_case"
+
+class NewsPostsTest < ApplicationSystemTestCase
+  # test "visiting the index" do
+  #   visit news_posts_url
+  #
+  #   assert_selector "h1", text: "NewsPost"
+  # end
+end