Created
January 4, 2010 22:58
-
-
Save bitzesty/268948 to your computer and use it in GitHub Desktop.
Getting up and running with MongoDB/MongoMapper
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
# config/enviroment.rb | |
config.gem 'mongo' | |
config.gem 'mongo_mapper' | |
# remove AR | |
config.frameworks -= [ :active_record, :active_resource ] |
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
# config/initializers/mongodb.rb | |
include MongoMapper | |
db_config = YAML::load(File.read(File.join(Rails.root, "/config/mongodb.yml"))) | |
if db_config[Rails.env] && db_config[Rails.env]['adapter'] == 'mongodb' | |
mongo = db_config[Rails.env] | |
MongoMapper.connection = Mongo::Connection.new(mongo['host'] || 'localhost', | |
mongo['port'] || 27017, | |
:logger => Rails.logger) | |
MongoMapper.database = mongo['database'] | |
if mongo['username'] && mongo['password'] | |
MongoMapper.database.authenticate(mongo['username'], mongo['password']) | |
end | |
end | |
ActionController::Base.rescue_responses['MongoMapper::DocumentNotFound'] = :not_found | |
# Used for image uploads | |
# CarrierWave.configure do |config| | |
# mongo = db_config[Rails.env] | |
# config.grid_fs_database = mongo['database'] | |
# config.grid_fs_host = mongo['host'] || 'localhost' | |
# config.grid_fs_access_url = "gridfs" | |
# config.grid_fs_username = mongo['username'] | |
# config.grid_fs_password = mongo['password'] | |
# end | |
# It's also possible to define indexes in the the model itself; however, | |
# a few issues are being worked out still. This is a temporary solution. | |
# Comment.ensure_index([["story_id", 1], ["path", 1], ["points", -1]]) | |
# MongoMapper.ensure_indexes! | |
# Handle passenger forking. | |
# if defined?(PhusionPassenger) | |
# PhusionPassenger.on_event(:starting_worker_process) do |forked| | |
# MongoMapper.database.connect_to_master if forked | |
# 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
# config/mongodb.yml | |
base: &base | |
adapter: mongodb | |
database: coolapp | |
#These are needed to authenticate with your db | |
#should it run on another server | |
host: genesis.mongohq.com | |
username: your-username | |
password: your-password | |
development: | |
<<: *base | |
test: | |
<<: *base | |
database: coolapp-test | |
production: | |
<<: *base |
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
gem install mongo_mapper | |
gem install mongo_ext #the c extensions (for production) | |
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
# lib/multi_parameter_attributes.rb | |
module MultiParameterAttributes | |
def attributes=(attrs) | |
multi_parameter_attributes = [] | |
attrs.each do |name, value| | |
return if attrs.blank? | |
if name.to_s.include?("(") | |
multi_parameter_attributes << [ name, value ] | |
else | |
writer_method = "#{name}=" | |
if respond_to?(writer_method) | |
self.send(writer_method, value) | |
else | |
self[name.to_s] = value | |
end | |
end | |
end | |
assign_multiparameter_attributes(multi_parameter_attributes) | |
end | |
def assign_multiparameter_attributes(pairs) | |
execute_callstack_for_multiparameter_attributes( | |
extract_callstack_for_multiparameter_attributes(pairs) | |
) | |
end | |
def execute_callstack_for_multiparameter_attributes(callstack) | |
callstack.each do |name, values_with_empty_parameters| | |
# in order to allow a date to be set without a year, we must keep the empty values. | |
# Otherwise, we wouldn't be able to distinguish it from a date with an empty day. | |
values = values_with_empty_parameters.reject(&:nil?) | |
if values.any? | |
key = self.class.keys[name] | |
raise ArgumentError, "Unknown key #{name}" if key.nil? | |
klass = key.type | |
value = if Time == klass | |
Time.zone.local(*values) | |
elsif Date == klass | |
begin | |
values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end | |
Date.new(*values) | |
rescue ArgumentError => ex # if Date.new raises an exception on an invalid date | |
Time.zone.local(*values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates | |
end | |
else | |
klass.new(*values) | |
end | |
writer_method = "#{name}=" | |
if respond_to?(writer_method) | |
self.send(writer_method, value) | |
else | |
self[name.to_s] = value | |
end | |
end | |
end | |
end | |
def extract_callstack_for_multiparameter_attributes(pairs) | |
attributes = { } | |
for pair in pairs | |
multiparameter_name, value = pair | |
attribute_name = multiparameter_name.split("(").first | |
attributes[attribute_name] = [] unless attributes.include?(attribute_name) | |
attributes[attribute_name] << [ find_parameter_position(multiparameter_name), value ] | |
end | |
attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } } | |
end | |
def find_parameter_position(multiparameter_name) | |
multiparameter_name.scan(/\(([0-9]*).*\)/).first.first | |
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
# models/comment.rb | |
class Comment | |
# Class Configuration ::::::::::::::::::::::::::::::::::::::::::::: | |
include MongoMapper::Document | |
# Attributes :::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
key :message, String | |
key :message_html, String | |
key :user_id, ObjectId | |
key :username, String | |
timestamps! | |
# Validations ::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
validates_presence_of :message | |
# Assocations ::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
belongs_to :user | |
# Callbacks ::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
before_create :set_username, :htmlify | |
after_create :increment_comment_count | |
private | |
def increment_comment_count | |
User.increment(user_id, :comment_count => 1) | |
end | |
def htmlify | |
self.message_html = RedCloth.new(message).to_html | |
end | |
def set_username | |
self.username = self.user.username | |
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
# models/user.rb | |
class User | |
# Class Configuration ::::::::::::::::::::::::::::::::::::::::::::: | |
include MongoMapper::Document | |
devise :authenticatable, :recoverable, :rememberable | |
# Attributes :::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
key :email, String | |
key :username, String | |
key :comment_count, Integer | |
key :encrypted_password, String | |
key :password_salt, String | |
key :reset_password_token, String | |
key :remember_token, String | |
key :remember_created_at, Time | |
key :sign_in_count, Integer | |
key :current_sign_in_at, Time | |
key :current_sign_in_ip, String | |
timestamps! | |
# Validations ::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
RegEmailName = '[\w\.%\+\-]+' | |
RegDomainHead = '(?:[A-Z0-9\-]+\.)+' | |
RegDomainTLD = '(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)' | |
RegEmailOk = /\A#{RegEmailName}@#{RegDomainHead}#{RegDomainTLD}\z/i | |
validates_length_of :email, :within => 6..100, :allow_blank => true | |
validates_format_of :email, :with => RegEmailOk, :allow_blank => true | |
# Assocations ::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
many :comments | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment