-
-
Save marfarma/180082 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# You can override these if you want in environment initializers: | |
COUCHDB_HOST = 'http://127.0.0.1:5984' unless defined?(COUCHDB_HOST) | |
COUCHDB_DB_NAME = "learnhub_#{Rails.env}" unless defined?(COUCHDB_DB_NAME) | |
# This stuff should stay here: | |
COUCHDB_SERVER = CouchRest.new(COUCHDB_HOST) | |
COUCHDB_DATABASE = COUCHDB_SERVER.database!(COUCHDB_DB_NAME) | |
CouchRest::Model.default_database = COUCHDB_DATABASE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NoMethodError (You have a nil object when you didn't expect it! | |
The error occurred while evaluating nil.view): | |
/opt/local/lib/ruby/gems/1.8/gems/jchris-couchrest-0.12.2/lib/couchrest/core/design.rb:84:in `fetch_view' | |
/opt/local/lib/ruby/gems/1.8/gems/jchris-couchrest-0.12.2/lib/couchrest/core/design.rb:42:in `view' | |
/opt/local/lib/ruby/gems/1.8/gems/jchris-couchrest-0.12.2/lib/couchrest/core/model.rb:392:in `fetch_view' | |
/opt/local/lib/ruby/gems/1.8/gems/jchris-couchrest-0.12.2/lib/couchrest/core/model.rb:383:in `fetch_view_with_docs' | |
/opt/local/lib/ruby/gems/1.8/gems/jchris-couchrest-0.12.2/lib/couchrest/core/model.rb:346:in `view' | |
/opt/local/lib/ruby/gems/1.8/gems/jchris-couchrest-0.12.2/lib/couchrest/core/model.rb:327:in `method_missing' | |
/lib/user_update_methods.rb:12:in `latest_update' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UserUpdate < CouchRest::Model | |
class ValidationError < StandardError; end | |
unique_id :slug | |
key_reader :slug | |
key_accessor :timestamp | |
key_accessor :user_id | |
key_accessor :user_username | |
key_accessor :body | |
view_by :slug, :descending => true | |
view_by :user_id, :descending => true | |
before :save, :validate | |
before :save, :create_and_set_slug | |
before :save, :compress_links_in_body | |
after :save, :increment_user_counter_cache | |
after :destroy, :decrement_user_counter_cache | |
def self.build(attrs = {}) | |
user = attrs.delete(:user) | |
if user | |
attrs[:user_id] = user.id | |
attrs[:user_username] = user.username | |
end | |
new attrs | |
end | |
def dom_id | |
new_document ? 'new_user_update' : "user_update_#{user_username}_#{timestamp}" | |
end | |
def created_at | |
Time.at(timestamp.to_i) | |
end | |
def to_s | |
body | |
end | |
private | |
def validate | |
raise ValidationError, 'User ID is required to store document.' if self['user_id'].blank? | |
raise ValidationError, 'Username is required to store document.' if self['user_username'].blank? | |
raise ValidationError, 'Your update can not be blank.' if self['body'].blank? | |
raise ValidationError, 'Your update may not exceed 140 characters.' if self['body'].length > 140 | |
end | |
def compress_links_in_body | |
self['body'] = Bitly.compress_urls_in(body) | |
end | |
def increment_user_counter_cache | |
User.async_execute(:increment_user_updates_count, self['user_id']) if new_document? | |
end | |
def decrement_user_counter_cache | |
User.async_execute(:decrement_user_updates_count, self['user_id']) | |
end | |
def create_and_set_slug | |
self['timestamp'] = Time.now.to_i if new_document? && !self['timestamp'] | |
self['slug'] = "#{self['user_username']}/#{self['timestamp']}" if new_document? | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# These are mixed in to my User class (which an ActiveRecord model) | |
module UserUpdateMethods | |
def user_update_by_timestamp(timestamp) | |
UserUpdate.get("#{username}/#{timestamp}") | |
end | |
def user_updates | |
UserUpdate.by_user_id(:key => id) | |
end | |
def latest_update | |
UserUpdate.by_user_id(:key => id, :limit => 1).try(:first) | |
end | |
def create_user_update(attrs) | |
raise ArgumentError, "attrs must be a Hash, not: #{attrs.class}" unless attrs.is_a?(Hash) | |
attrs.symbolize_keys! | |
uu = UserUpdate.build(:user => self, :body => attrs[:body]) | |
uu.save | |
uu | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'test/unit/../test_helper' | |
class UserUpdateTest < ActiveSupport::TestCase | |
context 'UserUpdate.get' do | |
context 'for an existing document' do | |
setup do | |
refresh_test_data! | |
@user_update = UserUpdate.get('cnielsen/1000000003') | |
end | |
should 'return the document as an instantiated UserUpdate object' do | |
assert_instance_of UserUpdate, @user_update | |
end | |
should 'return the document that was requested' do | |
assert_equal 'cnielsen/1000000003', @user_update['slug'] | |
end | |
end | |
context 'for a non-existing document' do | |
should 'raise an error' do | |
assert_raise RestClient::ResourceNotFound do | |
UserUpdate.get('cnielsen/0') | |
end | |
end | |
end | |
end | |
context 'A user with many updates' do | |
setup do | |
refresh_test_data! | |
@user = users(:cnielsen) | |
end | |
should 'have many user_updates' do | |
deny_empty @user.user_updates | |
end | |
should 'have a pesudo #user_update_by_timestamp method for UserUpdate.get' do | |
assert_equal 'Update 5.', @user.user_update_by_timestamp('1000000004').body | |
end | |
should 'have a #latest_update method that returns the latest update' do | |
assert_equal 'cnielsen/1000000004', @user.latest_update.slug | |
end | |
end | |
context 'A UserUpdate instance' do | |
context 'with valid attributes' do | |
setup do | |
reset_couchdb! | |
@user_update = UserUpdate.build( | |
:user => users(:cnielsen), | |
:body => 'CouchDB is fantastic!') | |
end | |
should 'save without any problems' do | |
assert_nothing_raised { @user_update.save } | |
assert_nothing_raised { @user_update.destroy } | |
end | |
should 'have a timestamp automatically set after being saved' do | |
assert_nothing_raised { @user_update.save } | |
assert_instance_of Bignum, @user_update.timestamp | |
end | |
end | |
context 'with no username' do | |
setup do | |
@user_update = UserUpdate.build( | |
:body => 'CouchDB is wicked sexy!') | |
end | |
should 'raise a ValidationError on save' do | |
assert_raise(UserUpdate::ValidationError) { @user_update.save } | |
end | |
end | |
context 'with no body' do | |
setup { @user_update = UserUpdate.build(:user => users(:cnielsen)) } | |
should 'raise a ValidationError on save' do | |
assert_raise(UserUpdate::ValidationError) { @user_update.save } | |
end | |
end | |
end | |
private | |
def refresh_test_data! | |
reset_couchdb! | |
carsten = User.find(2) | |
wes = User.find(1) | |
john = User.find(3) | |
[ { :user => carsten, :body => 'Update 1.', :timestamp => 1000000000 }, | |
{ :user => carsten, :body => 'Update 2.', :timestamp => 1000000001 }, | |
{ :user => carsten, :body => 'Update 3.', :timestamp => 1000000002 }, | |
{ :user => carsten, :body => 'Update 4.', :timestamp => 1000000003 }, | |
{ :user => carsten, :body => 'Update 5.', :timestamp => 1000000004 }, | |
{ :user => wes, :body => 'Update 1.', :timestamp => 1000000000 }, | |
{ :user => wes, :body => 'Update 2.', :timestamp => 1000000001 }, | |
{ :user => wes, :body => 'Update 3.', :timestamp => 1000000002 }, | |
{ :user => wes, :body => 'Update 4.', :timestamp => 1000000003 }, | |
{ :user => john, :body => 'Update 1.', :timestamp => 1000000000 }, | |
{ :user => john, :body => 'Update 2.', :timestamp => 1000000001 }, | |
{ :user => john, :body => 'Update 3.', :timestamp => 1000000002 } | |
].each { |u| UserUpdate.build(u).save } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment