An example use would be:
class Contact < DominoRecord
attr_accessor :email_address, :first_name, :last_name
validates_presence_of :first_name, :last_name, :email_address
validates_format_of :email_address, :with =>
/^\s*(?:(?:[^,@\s]+)@(?:(?:[-a-z0-9]+\.)+[a-z]{2,}\s*(,\s*|\z)))+$/i,
:message => "must be a valid email address",
:on => :create
@@database_name = "contacts.nsf" #your database here
@@server_name = 'www/projectlounge' #your server here
end
It currently uses the OLE/COM bridge to get to domino so only will work on windows at this stage. The next step would be to compile it with the NotesAPI to allow it to work on all platforms.
The model source code is here (I do not maintain this anymore but happy for others to take it on under LGPL):
require 'win32ole'
class DominoRecord
attr_accessor :form
def save
@document = @@database.CreateDocument
form = self.class.to_s.downcase
@document.ReplaceItemValue "form", form
self.instance_variables.each do |inst|
field_name = inst.sub(/[@]/, '')
field_value = self.instance_variable_get(inst)
@document.ReplaceItemValue field_name, field_value.to_s
end
@document.Save(true, false)
end
def save!;
save
end
def update_attribute; end
def new_record?; end
include ActiveRecord::Validations
@@session = nil
@@database = nil
@@database_name = nil
@@server_name = nil
def [](key)
instance_variable_get(key)
end
def self.find(*args)
options = extract_options_from_args!(args)
validate_find_options(options)
case args.first
when :first then
@document = find_initial(options)
when :all then find_every(options)
else
@document = find_from_ids(args, options)
end
record = self.new
@document.Items.each do |item|
record.send(item.Name.downcase + "=", item.Text) unless ["document", "errors"].include?(item.Name)
end
record
end
def DominoRecord.human_attribute_name(attribute_key_name)
ActiveRecord::Base.human_attribute_name(attribute_key_name)
end
def initialize(attributes=nil)
unless @@session
@@session = WIN32OLE.new('Lotus.NotesSession')
@@session.Initialize
end
@@database = @@session.GetDatabase(@@server_name,@@database_name) unless @@database
unless form == nil
fields = @@database.GetForm(form).Fields
else
fields = @@database.GetForm(self.class.to_s).Fields
end
fields.each { |field| self.class.__send__(:attr_accessor, field) }
return if attributes.nil?
attributes.each do |k, v|
send(k + "=", v)
end
end
def finalize
@@session.Finalize
end
def session
@@session
end
def database
@@database
end
def document
@document
end
def attributes=(attributes)
return if attributes.nil?
attributes.stringify_keys!
multi_parameter_attributes = []
attributes.each do |k, v|
send(k + "=", v)
end
end
def self.method_missing(method_id, *arguments)
unless @@session
@@session = WIN32OLE.new('Lotus.NotesSession')
@@session.Initialize
end
@@database = @@session.GetDatabase(@@server_name,@@database_name) unless @@database
if match = /find_by_([_a-zA-Z]\w*)/.match(method_id.to_s)
@view = @@database.GetView($1)
puts arguments
@document = @view.GetDocumentByKey(arguments[0])
record = self.new
@document.Items.each do |item|
record.send(item.Name.downcase + "=", item.Text) unless ["document", "errors"].include?(item.Name)
end
record
else
super
end
end
private
def self.find_initial(options)
#not working
end
def self.find_every(options)
#not working
end
def self.find_from_ids(ids, options)
#not working
end
def self.find_one(id, options)
if result = @@database.GetDocumentByUNID( id )
result
else
raise RecordNotFound, "Couldn't find #{name} with ID=#{id}#{conditions}"
end
end
def self.find_some(ids, options)
result = find_every(options)
if result.size == ids.size
result
else
raise RecordNotFound, "Couldn't find all #{name.pluralize} with IDs (#{ids_list})#{conditions}"
end
end
def self.extract_options_from_args!(args) #:nodoc:
args.last.is_a?(Hash) ? args.pop : {}
end
VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset,
:order, :select, :readonly, :group, :from ]
def self.validate_find_options(options) #:nodoc:
options.assert_valid_keys(VALID_FIND_OPTIONS)
end
end