Skip to content

Instantly share code, notes, and snippets.

@codesnik
Created March 7, 2010 18:08
Show Gist options
  • Save codesnik/324516 to your computer and use it in GitHub Desktop.
Save codesnik/324516 to your computer and use it in GitHub Desktop.
From f1a4da7b54468f815a8478b774da1e0fe47ff0d2 Mon Sep 17 00:00:00 2001
From: codesnik <[email protected]>
Date: Sat, 6 Mar 2010 23:54:38 +0300
Subject: [PATCH] migrates to datamapper
---
Gemfile | 71 ++++++++----
Gemfile.lock | 174 +++++++++++++++++++++--------
app/controllers/application_controller.rb | 2 +-
app/controllers/messages_controller.rb | 26 ++---
app/controllers/users_controller.rb | 12 +-
app/models/message.rb | 67 ++++++-----
app/models/user.rb | 8 +-
app/views/messages/_form.html.erb | 2 +-
app/views/messages/index.html.erb | 2 +-
app/views/messages/show.html.erb | 2 +-
10 files changed, 239 insertions(+), 127 deletions(-)
diff --git a/Gemfile b/Gemfile
index d5222c7..1d524c1 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,36 +1,57 @@
source 'http://gemcutter.org'
-gem 'rails', :git => 'git://github.com/rails/rails'
+git 'git://github.com/rails/rails.git'
-gem 'sqlite3-ruby', :require => 'sqlite3'
+gem 'activesupport', '~> 3.0.0.beta1', :require => 'active_support'
+gem 'actionpack', '~> 3.0.0.beta1', :require => 'action_pack'
+gem 'railties', '~> 3.0.0.beta1', :require => 'rails'
-gem 'will_paginate', '3.0.pre'
+gem 'actionmailer', '~> 3.0.0.beta1', :require => 'action_mailer'
-gem 'RedCloth'
+gem 'data_objects', '~> 0.10.1'
+gem 'do_sqlite3', '~> 0.10.1'
+
+# You can use any of the other available database adapters.
+# This is only a small excerpt of the list of all available adapters
+# Have a look at
+#
+# http://wiki.github.com/datamapper/dm-core/adapters
+# http://wiki.github.com/datamapper/dm-core/community-plugins
+#
+# for a rather complete list of available datamapper adapters and plugins
-# Use mongrel as the web server
-# gem 'mongrel'
+# gem 'do_mysql', '~> 0.10.1'
+# gem 'do_postgres', '~> 0.10.1'
+# gem 'do_oracle', '~> 0.10.1'
-# Deploy with Capistrano
-# gem 'capistrano'
+git 'git://github.com/snusnu/dm-core.git', 'branch' => 'active_support'
+git "git://github.com/snusnu/dm-more.git", 'branch' => 'active_support'
-# Bundle the extra gems:
-# gem 'bj'
-# gem 'hpricot', '0.6'
-# gem 'sqlite3-ruby', :require => 'sqlite3'
-# gem 'aws-s3', :require => 'aws/s3'
+gem 'dm-core', '~> 0.10.2'
+gem 'dm-types', '~> 0.10.2'
+gem 'dm-validations', '~> 0.10.2'
+gem 'dm-constraints', '~> 0.10.2'
+gem 'dm-aggregates', '~> 0.10.2'
+gem 'dm-timestamps', '~> 0.10.2'
+gem 'dm-migrations', '~> 0.10.2'
+gem 'dm-observer', '~> 0.10.2'
-# Bundle gems for certain environments:
-# gem 'rspec', :group => :test
+git 'git://github.com/datamapper/dm-rails.git'
-group :test do
- gem 'mocha'
- gem 'factory_girl'
-end
+gem 'dm-rails', '~> 0.10.2'
+
+gem 'RedCloth'
-# group :console do
-# gem 'looksee'
-# gem 'wirble'
-# gem 'hirb'
-# gem 'ruby-debug'
-# end
+#git 'git://github.com/rspec/rspec.git'
+#git 'git://github.com/rspec/rspec-core.git'
+#git 'git://github.com/rspec/rspec-expectations.git'
+#git 'git://github.com/rspec/rspec-mocks.git'
+#git 'git://github.com/rspec/rspec-rails.git'
+
+#group(:test) do
+# gem 'rspec', '2.0.0.beta.1'
+# gem 'rspec-core', '2.0.0.beta.1', :require => 'rspec/core'
+# gem 'rspec-expectations', '2.0.0.beta.1', :require => 'rspec/expectations'
+# gem 'rspec-mocks', '2.0.0.beta.1', :require => 'rspec/mocks'
+# gem 'rspec-rails', '2.0.0.beta.1'
+#end
diff --git a/Gemfile.lock b/Gemfile.lock
index b466169..a492213 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,51 +1,99 @@
---
dependencies:
- rails:
+ dm-rails:
group:
- :default
- version: ">= 0"
- sqlite3-ruby:
+ version: ~> 0.10.2
+ data_objects:
group:
- :default
- version: ">= 0"
+ version: ~> 0.10.1
+ dm-validations:
+ group:
+ - :default
+ version: ~> 0.10.2
+ dm-types:
+ group:
+ - :default
+ version: ~> 0.10.2
+ railties:
+ group:
+ - :default
+ version: ~> 3.0.0.beta1
require:
- - sqlite3
- factory_girl:
+ - rails
+ dm-observer:
group:
- - :test
- version: ">= 0"
- will_paginate:
+ - :default
+ version: ~> 0.10.2
+ dm-aggregates:
group:
- :default
- version: = 3.0.pre
- mocha:
+ version: ~> 0.10.2
+ dm-timestamps:
group:
- - :test
- version: ">= 0"
+ - :default
+ version: ~> 0.10.2
+ dm-core:
+ group:
+ - :default
+ version: ~> 0.10.2
+ actionmailer:
+ group:
+ - :default
+ version: ~> 3.0.0.beta1
+ require:
+ - action_mailer
+ actionpack:
+ group:
+ - :default
+ version: ~> 3.0.0.beta1
+ require:
+ - action_pack
RedCloth:
group:
- :default
version: ">= 0"
+ dm-constraints:
+ group:
+ - :default
+ version: ~> 0.10.2
+ activesupport:
+ group:
+ - :default
+ version: ~> 3.0.0.beta1
+ require:
+ - active_support
+ dm-migrations:
+ group:
+ - :default
+ version: ~> 0.10.2
+ do_sqlite3:
+ group:
+ - :default
+ version: ~> 0.10.1
specs:
- builder:
version: 2.1.2
-- RedCloth:
- version: 4.2.2
- text-hyphen:
version: 1.0.0
+- RedCloth:
+ version: 4.2.3
- i18n:
version: 0.3.5
-- bundler:
- version: 0.9.9
-- arel:
- version: 0.2.1
-- will_paginate:
- version: 3.0.pre
-- factory_girl:
- version: 1.2.3
+- json_pure:
+ version: 1.2.2
- activemodel:
version: 3.0.0.beta1
- source: 0
+ source: 1
+- rack-mount:
+ version: 0.6.1
+- dm-aggregates:
+ version: 0.10.3
+ source: 3
+- dm-observer:
+ version: 0.10.3
+ source: 3
- mime-types:
version: "1.16"
- mail:
@@ -54,52 +102,82 @@ specs:
version: 1.0.0
- erubis:
version: 2.6.5
+- stringex:
+ version: 1.1.0
- thor:
version: 0.13.4
-- sqlite3-ruby:
- version: 1.2.5
+- data_objects:
+ version: 0.10.1
+- do_sqlite3:
+ version: 0.10.1.1
- memcache-client:
version: 1.7.8
- rack:
version: 1.1.0
- rack-test:
version: 0.5.3
-- rack-mount:
- version: 0.5.2
- actionpack:
version: 3.0.0.beta1
- source: 0
+ source: 1
- rake:
version: 0.8.7
-- mocha:
- version: 0.9.8
- railties:
version: 3.0.0.beta1
- source: 0
+ source: 1
+- addressable:
+ version: 2.1.1
+- dm-core:
+ version: 0.10.3
+ source: 2
+- dm-active_model:
+ version: 0.4.0
+- dm-migrations:
+ version: 0.10.3
+ source: 3
+- dm-constraints:
+ version: 0.10.3
+ source: 3
+- dm-timestamps:
+ version: 0.10.3
+ source: 3
+- uuidtools:
+ version: 2.1.1
+- dm-validations:
+ version: 0.10.3
+ source: 3
- text-format:
version: 1.0.0
- actionmailer:
version: 3.0.0.beta1
- source: 0
-- activerecord:
- version: 3.0.0.beta1
- source: 0
-- activeresource:
- version: 3.0.0.beta1
- source: 0
-- rails:
- version: 3.0.0.beta1
- source: 0
+ source: 1
- tzinfo:
version: 0.3.16
- activesupport:
version: 3.0.0.beta1
- source: 0
-hash: e33a93609acaf17202af726c69811f5fa0b98020
+ source: 1
+- dm-rails:
+ version: 0.10.2
+ source: 4
+- fastercsv:
+ version: 1.5.1
+- dm-types:
+ version: 0.10.3
+ source: 3
+hash: 5707cd0c643a882c4eb5b8d6570075d8af9cae2d
sources:
-- Git:
- uri: git://github.com/rails/rails
- git: git://github.com/rails/rails
- ref: 020fdb28ee1d1bdb2dd1aa182869eb2e7c6115cb
- Rubygems:
uri: http://gemcutter.org
+- Git:
+ uri: git://github.com/rails/rails.git
+ ref: e00bc711d8780d9c7018dec8a794cb0772cd3ad5
+- Git:
+ uri: git://github.com/snusnu/dm-core.git
+ branch: active_support
+ ref: 3998d0682e4249fdf67355906320cf8311af2ca7
+- Git:
+ uri: git://github.com/snusnu/dm-more.git
+ branch: active_support
+ ref: fa90ad9e9884a76f2cbc288780f62cfa4125a60d
+- Git:
+ uri: git://github.com/datamapper/dm-rails.git
+ ref: f2b8ee6b2649e7a7efb8cf383ef245ba10b474f5
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index ceda2aa..0aa193d 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base
# заглушка для эмуляции авторизованности
def current_user
@current_user ||= if session[:user_id]
- User.find(session[:user_id])
+ User.get(session[:user_id])
end
end
helper_method :current_user
diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb
index 0ac6c77..3671e29 100644
--- a/app/controllers/messages_controller.rb
+++ b/app/controllers/messages_controller.rb
@@ -7,27 +7,25 @@ class MessagesController < ApplicationController
before_filter :require_auth
- # не работает в текущей версии гема.
- #self.per_page = 5
-
# GET /messages
# GET /messages.json
def index
- @threads = Message.threads.with_user(current_user).ordered_by_activity \
- .paginate(:page => params[:page], :per_page => THREADS_PER_PAGE)
+ @threads = Message.ordered_by_activity.threads.with_user(current_user)
+ # .paginate(:page => params[:page], :per_page => THREADS_PER_PAGE)
- respond_with @messages
+ respond_with @threads
end
# GET /messages/1
# GET /messages/1.json -> выдаст весь тред. возможно надо менять
def show
- @thread = Message.find(params[:id]).thread
+ @thread = Message.get!(params[:id]).thread
forbid! unless allowed_to_view?(@thread)
- @messages = @thread.thread_messages \
- .paginate(:page => params[:page], :per_page => MESSAGES_PER_PAGE)
+ # .entries нужен, чтобы выбрать записи ДО того, как пометить их как прочтенные
+ @messages = @thread.thread_messages.ordered_by_creation.entries
+ # .paginate(:page => params[:page], :per_page => MESSAGES_PER_PAGE)
@thread.read!(current_user)
@@ -44,7 +42,7 @@ class MessagesController < ApplicationController
# GET /messages/1/reply
def reply
- @thread = Message.find(params[:id]).thread
+ @thread = Message.get!(params[:id]).thread
forbid! unless allowed_to_view?(@thread)
@@ -54,7 +52,7 @@ class MessagesController < ApplicationController
# GET /messages/1/edit
def edit
- @message = Message.find(params[:id])
+ @message = Message.get!(params[:id])
forbid! unless allowed_to_view?(@message)
forbid! 'изменение запрещено: сообщение уже прочитано' unless allowed_to_change?(@message)
@@ -79,13 +77,13 @@ class MessagesController < ApplicationController
# PUT /messages/1
# PUT /messages/1.json
def update
- @message = Message.find(params[:id])
+ @message = Message.get!(params[:id])
forbid! unless allowed_to_view?(@message)
forbid! 'изменение запрещено: сообщение уже прочитано' unless allowed_to_change?(@message)
respond_to do |format|
- if @message.update_attributes(params[:message])
+ if @message.update(params[:message])
format.html { redirect_to(@message, :notice => 'сообщение изменено') }
format.json { head :ok }
else
@@ -98,7 +96,7 @@ class MessagesController < ApplicationController
# DELETE /messages/1
# DELETE /messages/1.json
def destroy
- @message = Message.find(params[:id])
+ @message = Message.get!(params[:id])
forbid! unless allowed_to_change?(@message)
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index a9f5d72..b1cc464 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -3,7 +3,7 @@ class UsersController < ApplicationController
# аутентификация. здесь только для тестовых целей
# POST /users/1/login
def login
- self.current_user = User.find(params[:id])
+ self.current_user = User.get(params[:id])
redirect_to Message, :notice => 'аутентификация прошла успешно'
end
@@ -28,7 +28,7 @@ class UsersController < ApplicationController
# GET /users/1
# GET /users/1.xml
def show
- @user = User.find(params[:id])
+ @user = User.get(params[:id])
respond_to do |format|
format.html # show.html.erb
@@ -49,7 +49,7 @@ class UsersController < ApplicationController
# GET /users/1/edit
def edit
- @user = User.find(params[:id])
+ @user = User.get(params[:id])
end
# POST /users
@@ -71,10 +71,10 @@ class UsersController < ApplicationController
# PUT /users/1
# PUT /users/1.xml
def update
- @user = User.find(params[:id])
+ @user = User.get(params[:id])
respond_to do |format|
- if @user.update_attributes(params[:user])
+ if @user.update(params[:user])
format.html { redirect_to(@user, :notice => 'пользователь успешно обновлен') }
format.xml { head :ok }
else
@@ -87,7 +87,7 @@ class UsersController < ApplicationController
# DELETE /users/1
# DELETE /users/1.xml
def destroy
- @user = User.find(params[:id])
+ @user = User.get(params[:id])
@user.destroy
respond_to do |format|
diff --git a/app/models/message.rb b/app/models/message.rb
index 8280926..8e8a3a6 100644
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -1,35 +1,41 @@
-class Message < ActiveRecord::Base
- # обновляет updated_at у родительского сообщения, нужно для сортировки
- belongs_to :parent, :class_name => "Message", :touch => true
- belongs_to :sender, :class_name => "User"
- belongs_to :recipient, :class_name => "User"
- has_many :messages, :foreign_key => :parent_id, :dependent => :delete_all
+class Message
+ include DataMapper::Resource
- default_scope order('created_at desc')
- scope :threads, where(:parent_id => nil)
- scope :unread, where(:unread => true)
- scope :with_user, lambda { |user|
- where(["recipient_id = ? or sender_id = ?", user.id, user.id])
- }
- scope :written_by, lambda { |user| where(:sender_id => user.id) }
- scope :received_by, lambda { |user| where(:recipient_id => user.id) }
- scope :unread_by, lambda { |user| unread.received_by(user) }
- scope :ordered_by_activity, order('updated_at desc')
+ property :id, Serial
+ property :subject, String
+ property :body, Text, :required => true
+ property :unread, Boolean, :default => true, :required => true, :lazy => false
+ timestamps :at
- # что-то одно должно присутствовать
- validates_presence_of :body, :if => proc {|msg| msg.subject.blank? }
- validates_presence_of :sender, :recipient
+ belongs_to :parent, "Message", :required => false
+ belongs_to :sender, "User"
+ belongs_to :recipient, "User"
+ has n, :messages, :child_key => :parent_id # :dependent => :delete_all ?
- def thread_starter?; !parent_id end
+ # scopes
+ class << self
+ def ordered_by_creation; all(:order => :created_at.desc) end
+ def threads; all(:parent => nil) end
+ def unread; all(:unread => true) end
+ def with_user(user)
+ # all(:conditions => ["recipient_id = ? or sender_id = ?", user.id, user.id])
+ all(:recipient => user) + all(:sender => user)
+ end
+ def written_by(user); all(:sender => user) end
+ def received_by(user); all(:recipient => user) end
+ def unread_by(user); unread.received_by(user) end
+ def ordered_by_activity; all(:order => :updated_at.desc) end
+ end
+
+ def thread_starter?; !parent end
def reply?; !thread_starter? end
def thread; parent || self end
- def thread_id; parent_id || id end
- # TODO try to get this via association
def thread_messages
- #thread.messages + [thread]
- Message.where(["id = ? or parent_id = ?", thread_id, thread_id])
+ ## TODO try to get this via association
+ #Message.all(:id => thread.id) + Message.all(:parent => thread)
+ Message.all(:conditions => ["id = ? or parent_id = ?", thread.id, thread.id])
end
def thread_messages_count
@@ -37,7 +43,7 @@ class Message < ActiveRecord::Base
end
def new_reply(author)
- msg = thread.messages.build :sender => author
+ msg = thread.messages.new :sender => author
# можно писать в свой же тред
msg.recipient = (thread.sender == author) ? thread.recipient : thread.sender
msg
@@ -58,13 +64,16 @@ class Message < ActiveRecord::Base
end
def first_unread_or_last_read_for(reader)
- # last и first имеют противоположный смысл из-за default_scope
- # TODO избавиться от него?
- thread_messages.unread_by(reader).last || thread_messages.first
+ thread_messages.unread_by(reader).first(:order => :created_at.asc) ||
+ thread_messages.first(:order => :created_at.desc)
end
def read!(reader)
- thread_messages.unread_by(reader).update_all :unread => false
+ thread_messages.unread_by(reader).update! :unread => false
end
+ after :create do
+ # для сортировки в инбоксе
+ parent && parent.touch
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 4a57cf0..7be9ab4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,2 +1,8 @@
-class User < ActiveRecord::Base
+class User
+
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :name, String
+
end
diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb
index 9b67c95..86b450d 100644
--- a/app/views/messages/_form.html.erb
+++ b/app/views/messages/_form.html.erb
@@ -21,7 +21,7 @@
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
- <%= f.hidden_field :parent_id %>
+ <%= f.hidden_field :parent_id if @message.parent %>
<div class="actions">
<%= f.submit %>
</div>
diff --git a/app/views/messages/index.html.erb b/app/views/messages/index.html.erb
index d301c83..94b9c28 100644
--- a/app/views/messages/index.html.erb
+++ b/app/views/messages/index.html.erb
@@ -17,4 +17,4 @@
<% end %>
</table>
-<%= will_paginate @threads %>
+<%#= will_paginate @threads %>
diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb
index bdd6453..47987a0 100644
--- a/app/views/messages/show.html.erb
+++ b/app/views/messages/show.html.erb
@@ -21,4 +21,4 @@
<% end %>
<% end %>
-<%= will_paginate @messages %>
+<%#= will_paginate @messages %>
--
1.7.0+GitX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment