Create attachment model and hook it up to todo

An attachment has write permissions on group so that managing
attachments work from different users in same group, i.e. user apache
and user mail.
This commit is contained in:
Reinier Balt 2015-08-05 13:01:02 +02:00
parent 5499ac2a03
commit 2bd68fecb7
10 changed files with 121 additions and 39 deletions

1
.gitignore vendored
View file

@ -15,6 +15,7 @@
/db/*.db
/db/*.sqlite3
/db/*.sqlite3-journal
/db/assets/*
/log/*.log
/public/assets/
/tmp

20
app/models/attachment.rb Normal file
View file

@ -0,0 +1,20 @@
class Attachment < ActiveRecord::Base
belongs_to :todo, touch: true
has_attached_file :file,
url: '/:class/:id/:basename.:extension',
path: ":rails_root/db/assets/#{Rails.env}/:class/:id/:basename.:extension",
override_file_permissions: 0660
do_not_validate_attachment_file_type :file
# validates_attachment_content_type :file, :content_type => ["text/plain"]
before_destroy :delete_attached_file
private
def delete_attached_file
file = nil
save!
end
end

View file

@ -24,6 +24,7 @@ class Todo < ActiveRecord::Base
:source => :predecessor
has_many :pending_successors, -> {where('todos.state = ?', 'pending')}, :through => :predecessor_dependencies,
:source => :successor
has_many :attachments, dependent: :destroy
# scopes for states of this todo
scope :active, -> { where state: 'active' }

View file

@ -96,6 +96,7 @@ class User < ActiveRecord::Base
has_many :notes, -> { order "created_at DESC" }, dependent: :delete_all
has_one :preference, dependent: :destroy
has_many :attachments, through: :todos
validates_presence_of :login
validates_presence_of :password, if: :password_required?

View file

@ -106,6 +106,7 @@ Rails.application.routes.draw do
# Needed for /todos/tag/first.last.m to work
get 'todos/tag/:name' => 'todos#tag', :as => :tag, :format => false, :name => /.*/
get 'attachments/:id/:filename' => "todos#attachment"
get 'tags.autocomplete' => "todos#tags", :format => 'autocomplete'
get 'todos/done/tag/:name' => "todos#done_tag", :as => :done_tag
get 'todos/all_done/tag/:name' => "todos#all_done_tag", :as => :all_done_tag

View file

@ -0,0 +1,9 @@
class CreateAttachments < ActiveRecord::Migration
def change
create_table :attachments do |t|
t.references :todo, index: true
t.attachment :file
t.timestamps
end
end
end

View file

@ -11,11 +11,23 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150209233951) do
ActiveRecord::Schema.define(version: 20150805144100) do
create_table "attachments", force: true do |t|
t.integer "todo_id"
t.string "file_file_name"
t.string "file_content_type"
t.integer "file_file_size"
t.datetime "file_updated_at"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "attachments", ["todo_id"], name: "index_attachments_on_todo_id", using: :btree
create_table "contexts", force: true do |t|
t.string "name", null: false
t.integer "position"
t.integer "position", default: 0
t.integer "user_id", default: 1
t.datetime "created_at"
t.datetime "updated_at"
@ -86,9 +98,9 @@ ActiveRecord::Schema.define(version: 20150209233951) do
create_table "projects", force: true do |t|
t.string "name", null: false
t.integer "position"
t.integer "position", default: 0
t.integer "user_id", default: 1
t.text "description"
t.text "description", limit: 16777215
t.string "state", limit: 20, null: false
t.datetime "created_at"
t.datetime "updated_at"
@ -108,7 +120,7 @@ ActiveRecord::Schema.define(version: 20150209233951) do
t.integer "context_id", null: false
t.integer "project_id"
t.string "description", null: false
t.text "notes"
t.text "notes", limit: 16777215
t.string "state", limit: 20, null: false
t.datetime "start_from"
t.string "ends_on"
@ -141,7 +153,7 @@ ActiveRecord::Schema.define(version: 20150209233951) do
t.datetime "updated_at"
end
add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
add_index "sessions", ["session_id"], name: "sessions_session_id_index", using: :btree
create_table "taggings", force: true do |t|
t.integer "taggable_id"
@ -165,7 +177,7 @@ ActiveRecord::Schema.define(version: 20150209233951) do
t.integer "context_id", null: false
t.integer "project_id"
t.string "description", null: false
t.text "notes"
t.text "notes", limit: 16777215
t.datetime "created_at"
t.datetime "due"
t.datetime "completed_at"
@ -174,7 +186,7 @@ ActiveRecord::Schema.define(version: 20150209233951) do
t.string "state", limit: 20, null: false
t.integer "recurring_todo_id"
t.datetime "updated_at"
t.text "rendered_notes"
t.text "rendered_notes", limit: 16777215
end
add_index "todos", ["context_id"], name: "index_todos_on_context_id", using: :btree
@ -212,7 +224,7 @@ ActiveRecord::Schema.define(version: 20150209233951) do
create_table "users", force: true do |t|
t.string "login", limit: 80, null: false
t.string "crypted_password", limit: 60, null: false
t.string "crypted_password", limit: 60
t.string "token"
t.boolean "is_admin", default: false, null: false
t.string "first_name"

7
test/fixtures/attachments.yml vendored Normal file
View file

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

View file

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

View file

@ -542,4 +542,27 @@ class TodoTest < ActiveSupport::TestCase
assert_equal "<p><strong>test</strong></p>", todo.rendered_notes
end
def test_attachments_are_removed_after_delete
# Given a user and a todo withou any attachments
todo = @not_completed1
assert_equal 0, todo.attachments.count, "we start without attachments"
assert_equal 0, todo.user.attachments.count, "the user has no attachments"
# When I add a file as attachment to a todo of this user
attachment = todo.attachments.build
attachment.file = File.open(File.join(Rails.root, 'test', 'fixtures', 'email_with_multipart.txt'))
attachment.save!
new_path = attachment.file.path
# then the attachment should be there
assert File.exists?(new_path), "attachment should be on file system"
assert_equal 1, todo.attachments.reload.count, "should have one attachment"
# When I destroy the todo
todo.destroy!
# Then the attachement and file should nogt be there anymore
assert_equal 0, todo.user.attachments.reload.count
assert !File.exists?(new_path), "attachment should not be on file system"
end
end