diff --git a/Gemfile b/Gemfile index 2ab6deb..fd80595 100755 --- a/Gemfile +++ b/Gemfile @@ -43,7 +43,9 @@ gem 'jquery-rails' # Formbuilder for easier form generation gem 'formtastic', '~>2.2.1' -gem 'formtastic-bootstrap', '~>2.1.3' #, :git => "git://github.com/mjbellantoni/formtastic-bootstrap.git" + +# gem 'formtastic-bootstrap', '~>2.1.3' #, :git => "git://github.com/mjbellantoni/formtastic-bootstrap.git" +gem 'formtastic-bootstrap', '~>3.0.0' #, :git => "git://github.com/mjbellantoni/formtastic-bootstrap.git" # TinyMCE gem "tinymce-rails" , '~>4.1.0' diff --git a/app/assets/javascripts/comments.js.coffee b/app/assets/javascripts/comments.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/comments.js.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://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/themes/blue1/application.css.scss b/app/assets/stylesheets/themes/blue1/application.css.scss index a24cf52..28f08bb 100755 --- a/app/assets/stylesheets/themes/blue1/application.css.scss +++ b/app/assets/stylesheets/themes/blue1/application.css.scss @@ -115,3 +115,4 @@ $box-background: white; @import 'layout'; @import 'calendars'; +@import 'formtastic-bootstrap' \ No newline at end of file diff --git a/app/controllers/beispiele_controller.rb b/app/controllers/beispiele_controller.rb index 647c45f..1917613 100755 --- a/app/controllers/beispiele_controller.rb +++ b/app/controllers/beispiele_controller.rb @@ -17,7 +17,10 @@ class BeispieleController < ApplicationController def show # @lva = params([:lva]) unless params([:lva]).nil? @beispiel = Beispiel.find(params[:id]) - redirect_to @beispiel.lva + respond_to do |format| + format.html { redirect_to @beispiel.lva } + format.js + end end # GET /beispiele/new diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb new file mode 100644 index 0000000..7501c65 --- /dev/null +++ b/app/controllers/comments_controller.rb @@ -0,0 +1,83 @@ +class CommentsController < ApplicationController + def index + @comments=Comment.all + end + def show + @comment = Comment.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @comment } + end + end + def new + @comment = Comment.new + @comment.commentable=params[:commentable_type].constantize.find(params[:commentable_id]) unless params[:commentable_type].nil? or params[:commentable_id].nil? + respond_to do |format| + format.html # new.html.erb + format.json { render json: @comment } + format.js + end + end + + # GET /comments/1/edit + def edit + @comment = Comment.find(params[:id]) + end + + # POST /comments + # POST /comments.json + def create + params_new= params[:comment].select {|i| !["commentable_id", "commentable_type"].include?(i)} + + c = params[:comment][:commentable_type].constantize.find(params[:comment][:commentable_id]) unless params[:comment][:commentable_type].nil? or params[:comment][:commentable_id].nil? + + @comment = Comment.build_for(c, current_user,"", params_new) + #raise @comment.to_yaml.to_s + # @comment.commentable= c + + + + + respond_to do |format| + if @comment + format.html { redirect_to @comment.commentable, notice: 'Comment was successfully created.' } + format.json { render json: @comment, status: :created, location: @comment } + else + format.html { render action: "new" } + format.json { render json: @comment.errors, status: :unprocessable_entity } + end + end + end + + # PUT /comments/1 + # PUT /comments/1.json + def update + + params[:comment].select! {|i| !["commentable_id", "commentable_type"].include?(i)} + @comment = Comment.find(params[:id]) + @comment.commentable=params[:comment][:commentable_type].constantize.find(params[:comment][:commentable_id]) unless params[:comment][:commentable_type].nil? or params[:comment][:commentable_id].nil? + respond_to do |format| + + if @comment.update_attributes(params[:comment]) + format.html { redirect_to @comment.commentable, notice: 'Comment was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @comment.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /comments/1 + # DELETE /comments/1.json + def destroy + @comment = Comment.find(params[:id]) + @comment.destroy + + respond_to do |format| + format.html { redirect_to comments_url } + format.json { head :no_content } + end + end +end diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb new file mode 100644 index 0000000..0ec9ca5 --- /dev/null +++ b/app/helpers/comments_helper.rb @@ -0,0 +1,2 @@ +module CommentsHelper +end diff --git a/app/models/ability.rb b/app/models/ability.rb index 6193b32..3a6397c 100755 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -4,6 +4,8 @@ class Ability def initialize(user) loggedin=!(user.nil?) user ||= User.new # guest user (not logged in) + + can :manage, Comment #----------------------------------------------------- # Rechteverwaltung fuer Studien Modul can [:show, :index], Studium @@ -97,6 +99,8 @@ class Ability if user.has_role?("fetadmin") can :addfetuser, User can :addfetadmin, User + can :edit, User + can :manage, User end if user.has_role?("newsadmin") || user.has_role?( "fetadmin") || user.has_role?( "fetuser") diff --git a/app/models/beispiel.rb b/app/models/beispiel.rb index 8e0ba3c..9d94c06 100755 --- a/app/models/beispiel.rb +++ b/app/models/beispiel.rb @@ -16,7 +16,7 @@ class Beispiel < ActiveRecord::Base attr_accessible :desc, :name, :lva_id, :beispieldatei, :beispieldatei_cache, :datum acts_as_votable belongs_to :lva - + include IsCommentable mount_uploader :beispieldatei, AttachmentUploader validates :beispieldatei, :presence => true validates :name, :presence => true @@ -35,4 +35,7 @@ class Beispiel < ActiveRecord::Base "delete_type" => "DELETE" } end + def divid + "beispiel_"+id.to_s + end end diff --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100644 index 0000000..a074fd7 --- /dev/null +++ b/app/models/comment.rb @@ -0,0 +1,44 @@ +class Comment < ActiveRecord::Base + attr_accessible :text,:anonym, :intern, :hidden + # commentable depth, official, intern, anonym + acts_as_votable + acts_as_nested_set :scope => [:commentable_id, :commentable_type] + belongs_to :commentable, :polymorphic=> true + belongs_to :user + validate :text, :presence=>true + validate :user, :presence=>true + validate :commentable, :presence=>true + include IsCommentable + + def self.build_for(set_commentable, user, text,attr={}) + c = new + raise "Tried to build comment for non commentable" unless set_commentable.try(:is_commentable?) + c.user=user + c.text=text + c.assign_attributes(attr) + + unless set_commentable.class.to_s == "Comment" + c.commentable=set_commentable + c.save + else + + c.commentable=set_commentable.commentable + c.save + c.move_to_child_of(set_commentable) + end + c + end + def thumb_url + t_url= user.fetprofile.picture.thumb.url unless user.nil? or user.fetprofile.nil? + t_url + end + def divid + "comment_" + id.to_s + end + def formid +"comment_form_" + commentable_type + "_" + commentable_id.to_s + end + def self.formid_for(c) + "comment_form_" + c.class.to_s + "_" + c.id.to_s + end +end diff --git a/app/models/fetprofile.rb b/app/models/fetprofile.rb index bf367bf..1731382 100644 --- a/app/models/fetprofile.rb +++ b/app/models/fetprofile.rb @@ -16,7 +16,7 @@ class Fetprofile < ActiveRecord::Base attr_accessible :active, :desc, :fetmailalias, :nachname, :picture, :short, :vorname, :memberships_attributes, :remove_picture, :picture_cache, :plz, :street, :city, :instant,:skype, :telnr, :hdynr, :birth_day, :birth_month, :birth_year,:geschlecht - has_many :memberships, dependent: :delete_all + has_many :memberships, dependent: :destroy has_many :gremien, :through=> :membership mount_uploader :picture, PictureUploader has_paper_trail diff --git a/app/views/beispiele/_beispiel.html.erb b/app/views/beispiele/_beispiel.html.erb index b44dde7..15e3de1 100644 --- a/app/views/beispiele/_beispiel.html.erb +++ b/app/views/beispiele/_beispiel.html.erb @@ -1,5 +1,5 @@ - -
+
+
<%=link_to ffi1_icon("note20")+" " + beispiel.name, beispiel.beispieldatei.url, title: beispiel.desc %> @@ -7,7 +7,7 @@ <%= I18n.t("file.size") + ": " + (beispiel.beispieldatei.size/1024.0).round(2).to_s %>KiB
<%= if can?(:like, beispiel) -link_to ffi1_icon("like3")+" like" + "("+beispiel.get_likes.size.to_s+")", like_beispiel_path(beispiel),title: "liked by " + ((current_user.liked?(beispiel)) ? ("you and " + ((beispiel.get_likes.size - 1).to_s + " others")) : beispiel.get_likes.size.to_s) +link_to ffi1_icon("like3")+" like" + "("+beispiel.get_likes.size.to_s+")", like_beispiel_path(beispiel),title: "liked by " + ((current_user.liked?(beispiel)) ? ("you and " + ((beispiel.get_likes.size - 1).to_s + " others")) : beispiel.get_likes.size.to_s), remote: true else "liked by " + beispiel.get_likes.size.to_s end @@ -15,7 +15,7 @@ end <%= if can?(:dislike, beispiel) -link_to ffi1_icon("dislike")+" dislike" + "("+beispiel.get_dislikes.size.to_s+")", dislike_beispiel_path(beispiel),title:"disliked by " + ((current_user.disliked?(beispiel)) ? ("you and " + ((beispiel.get_dislikes.size - 1).to_s + " others")) : beispiel.get_dislikes.size.to_s) +link_to ffi1_icon("dislike")+" dislike" + "("+beispiel.get_dislikes.size.to_s+")", dislike_beispiel_path(beispiel),title:"disliked by " + ((current_user.disliked?(beispiel)) ? ("you and " + ((beispiel.get_dislikes.size - 1).to_s + " others")) : beispiel.get_dislikes.size.to_s) , remote: true else "disliked by " + beispiel.get_dislikes.size.to_s end @@ -23,10 +23,17 @@ end %> <%= link_to ff_icon("icon-pencil")+" edit", edit_beispiel_path(beispiel) if can? :edit, beispiel%> -<%= link_to ff_icon("icon-remove")+" delete", beispiel_path(beispiel), :method=>:delete, :data=>{:confirm=>I18n.t('beispiel.sure')} if can? :delete, beispiel %>
+<%= link_to ff_icon("icon-remove")+" delete", beispiel_path(beispiel), :method=>:delete, :data=>{:confirm=>I18n.t('beispiel.sure')} if can? :delete, beispiel %> +<%= link_to "Refresh", beispiel, remote: true %>
<%= beispiel.desc %>
+
<%= render partial:"comments/comments", object: beispiel.comments.roots %>
+<%= link_to "comment" , new_comment_path( commentable_type: "Beispiel", commentable_id: beispiel.id), remote:true %> +
+
+ +
diff --git a/app/views/beispiele/refresh.js.erb b/app/views/beispiele/refresh.js.erb new file mode 100644 index 0000000..1398a00 --- /dev/null +++ b/app/views/beispiele/refresh.js.erb @@ -0,0 +1 @@ +$("#<%= @beispiel.divid %>").replaceWith("<%= escape_javascript ( render @beispiel ) %>") \ No newline at end of file diff --git a/app/views/beispiele/show.js.erb b/app/views/beispiele/show.js.erb new file mode 100644 index 0000000..c384d9a --- /dev/null +++ b/app/views/beispiele/show.js.erb @@ -0,0 +1 @@ +$("<%= '#' + @beispiel.divid %>").replaceWith("<%= escape_javascript render @beispiel %>") \ No newline at end of file diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb new file mode 100644 index 0000000..90e35c8 --- /dev/null +++ b/app/views/comments/_comment.html.erb @@ -0,0 +1,12 @@ +
+ <%= image_tag comment.thumb_url %> +
+ <%= comment.user.try(:email) %> (<%= I18n.l(comment.created_at) %>): <%= comment.text %> +<%= link_to "comment" , new_comment_path( commentable_type: "Comment", commentable_id: comment.id), remote:true %> + <%= render partial:"comments/comments", object: comment.children if comment.children.size >0 %> + +
+ +
+
+
diff --git a/app/views/comments/_comments.html.erb b/app/views/comments/_comments.html.erb new file mode 100644 index 0000000..4404446 --- /dev/null +++ b/app/views/comments/_comments.html.erb @@ -0,0 +1,7 @@ +
+ +
diff --git a/app/views/comments/_form.html.erb b/app/views/comments/_form.html.erb new file mode 100644 index 0000000..0f9d2c8 --- /dev/null +++ b/app/views/comments/_form.html.erb @@ -0,0 +1,14 @@ +
+ <%= semantic_form_for form , remote:true, html: {class: "form-inline"} do |f| %> + <%= f.inputs do %> + <%= f.input :commentable_id, as: :hidden %> + <%= f.input :commentable_type, as: :hidden %> + <%= f.input :text, as: :string %> + <%= f.input :anonym %> + <% end %> + + <%= f.actions do %> + <%= f.action :submit, :as => :input %> + <% end %> +<% end %> +
diff --git a/app/views/comments/edit.html.erb b/app/views/comments/edit.html.erb new file mode 100644 index 0000000..ba1980e --- /dev/null +++ b/app/views/comments/edit.html.erb @@ -0,0 +1,6 @@ +

Editing comment

+ +<%= render 'form', object: @comment %> + +<%= link_to 'Show', @comment %> | +<%= link_to 'Back', comments_path %> diff --git a/app/views/comments/index.html.erb b/app/views/comments/index.html.erb new file mode 100644 index 0000000..bfa38fe --- /dev/null +++ b/app/views/comments/index.html.erb @@ -0,0 +1,21 @@ +

Listing comments

+ + + + + + + + +<% @comments.each do |comment| %> + + + + + +<% end %> +
<%= link_to 'Show', comment %><%= link_to 'Edit', edit_comment_path(comment) %><%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' } %>
+ +
+ +<%= link_to 'New Comment', new_comment_path %> diff --git a/app/views/comments/new.html.erb b/app/views/comments/new.html.erb new file mode 100644 index 0000000..4d10894 --- /dev/null +++ b/app/views/comments/new.html.erb @@ -0,0 +1,5 @@ +

New comment

+ +<%= render partial: 'form', object: @comment %> + +<%= link_to 'Back', comments_path %> diff --git a/app/views/comments/new.js.erb b/app/views/comments/new.js.erb new file mode 100644 index 0000000..814b5c9 --- /dev/null +++ b/app/views/comments/new.js.erb @@ -0,0 +1 @@ +$("#<%= @comment.formid %>").replaceWith("<%= escape_javascript render partial: "form", object: @comment %>") \ No newline at end of file diff --git a/app/views/comments/show.html.erb b/app/views/comments/show.html.erb new file mode 100644 index 0000000..a0e0552 --- /dev/null +++ b/app/views/comments/show.html.erb @@ -0,0 +1,6 @@ +

<%= notice %>

+ +<%= render @comment %> + +<%= link_to 'Edit', edit_comment_path(@comment) %> | +<%= link_to 'Back', comments_path %> diff --git a/config/application.rb b/config/application.rb index 38f38e4..4c31c97 100755 --- a/config/application.rb +++ b/config/application.rb @@ -2,6 +2,8 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' require File.expand_path('lib/like_voteable.rb') +require File.expand_path('lib/is_commentable.rb') + if defined?(Bundler) # If you precompile assets before deploying to production, use this line Bundler.require(*Rails.groups(:assets => %w(development test))) diff --git a/config/routes.rb b/config/routes.rb index d01752e..085095d 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,7 @@ Fetsite::Application.routes.draw do + resources :comments + + themes_for_rails devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } resources :home, :only=>[:index] do @@ -127,7 +130,7 @@ Fetsite::Application.routes.draw do end end end - + resources :comments resources :home, :only=>[:index] do get :search, :on => :collection collection do diff --git a/db/migrate/20140723172934_create_comments.rb b/db/migrate/20140723172934_create_comments.rb new file mode 100644 index 0000000..8b0ab02 --- /dev/null +++ b/db/migrate/20140723172934_create_comments.rb @@ -0,0 +1,19 @@ +class CreateComments < ActiveRecord::Migration + def change + create_table :comments do |t| + t.integer :user_id + t.integer :commentable_id + t.string :commentable_type + t.text :text + t.integer :parent_id + t.integer :lft + t.integer :rgt + t.integer :depth + t.boolean :hidden + t.boolean :official + t.boolean :intern + t.boolean :anonym + t.timestamps + end + end +end diff --git a/lib/is_commentable.rb b/lib/is_commentable.rb new file mode 100644 index 0000000..c5c1d56 --- /dev/null +++ b/lib/is_commentable.rb @@ -0,0 +1,20 @@ +module IsCommentable + def self.included(base) + base.class_eval do + include InstanceMethods + has_many :comments, as: :commentable, dependent: :destroy +# extend ClassMethods + + end + + end + module InstanceMethods + def is_commentable? + true + end + def comment(user, text, attr={}) + comments << Comment.build_for(self, user, text, attr) + end + end + +end diff --git a/lib/like_voteable.rb b/lib/like_voteable.rb index da4f3a9..6db22f9 100644 --- a/lib/like_voteable.rb +++ b/lib/like_voteable.rb @@ -13,7 +13,15 @@ module LikeVoteable else @obj.liked_by current_user end - redirect_to @obj + respond_to do |format| + format.html { + redirect_to @obj + } + format.js { + render :show + } + # + end end def dislike @obj=controller_name.classify.constantize.find(params[:id]) @@ -22,7 +30,17 @@ module LikeVoteable else @obj.disliked_by current_user end - redirect_to @obj + + respond_to do |format| + format.html { + redirect_to @obj + } + format.js { + render :show + } + # + end + end end diff --git a/spec/factories/comments.rb b/spec/factories/comments.rb new file mode 100644 index 0000000..3ad06c6 --- /dev/null +++ b/spec/factories/comments.rb @@ -0,0 +1,6 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :comment do + end +end diff --git a/spec/helpers/comments_helper_spec.rb b/spec/helpers/comments_helper_spec.rb new file mode 100644 index 0000000..4cda1ad --- /dev/null +++ b/spec/helpers/comments_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the CommentsHelper. For example: +# +# describe CommentsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +describe CommentsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb new file mode 100644 index 0000000..505e33d --- /dev/null +++ b/spec/models/comment_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Comment do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/comments_spec.rb b/spec/requests/comments_spec.rb new file mode 100644 index 0000000..7a38a46 --- /dev/null +++ b/spec/requests/comments_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "Comments" do + describe "GET /comments" do + it "works! (now write some real specs)" do + # Run the generator again with the --webrat flag if you want to use webrat methods/matchers + get comments_path + response.status.should be(200) + end + end +end diff --git a/spec/routing/comments_routing_spec.rb b/spec/routing/comments_routing_spec.rb new file mode 100644 index 0000000..73c8056 --- /dev/null +++ b/spec/routing/comments_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe CommentsController do + describe "routing" do + + it "routes to #index" do + get("/comments").should route_to("comments#index") + end + + it "routes to #new" do + get("/comments/new").should route_to("comments#new") + end + + it "routes to #show" do + get("/comments/1").should route_to("comments#show", :id => "1") + end + + it "routes to #edit" do + get("/comments/1/edit").should route_to("comments#edit", :id => "1") + end + + it "routes to #create" do + post("/comments").should route_to("comments#create") + end + + it "routes to #update" do + put("/comments/1").should route_to("comments#update", :id => "1") + end + + it "routes to #destroy" do + delete("/comments/1").should route_to("comments#destroy", :id => "1") + end + + end +end diff --git a/spec/views/comments/edit.html.erb_spec.rb b/spec/views/comments/edit.html.erb_spec.rb new file mode 100644 index 0000000..877a489 --- /dev/null +++ b/spec/views/comments/edit.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "comments/edit" do + before(:each) do + @comment = assign(:comment, stub_model(Comment)) + end + + it "renders the edit comment form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form[action=?][method=?]", comment_path(@comment), "post" do + end + end +end diff --git a/spec/views/comments/index.html.erb_spec.rb b/spec/views/comments/index.html.erb_spec.rb new file mode 100644 index 0000000..374f61e --- /dev/null +++ b/spec/views/comments/index.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "comments/index" do + before(:each) do + assign(:comments, [ + stub_model(Comment), + stub_model(Comment) + ]) + end + + it "renders a list of comments" do + render + # Run the generator again with the --webrat flag if you want to use webrat matchers + end +end diff --git a/spec/views/comments/new.html.erb_spec.rb b/spec/views/comments/new.html.erb_spec.rb new file mode 100644 index 0000000..bcba931 --- /dev/null +++ b/spec/views/comments/new.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "comments/new" do + before(:each) do + assign(:comment, stub_model(Comment).as_new_record) + end + + it "renders new comment form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form[action=?][method=?]", comments_path, "post" do + end + end +end diff --git a/spec/views/comments/show.html.erb_spec.rb b/spec/views/comments/show.html.erb_spec.rb new file mode 100644 index 0000000..1a6927b --- /dev/null +++ b/spec/views/comments/show.html.erb_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe "comments/show" do + before(:each) do + @comment = assign(:comment, stub_model(Comment)) + end + + it "renders attributes in

" do + render + # Run the generator again with the --webrat flag if you want to use webrat matchers + end +end