Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Create MailForm::Shim to use MailForm with non ActiveModel resources.

  • Loading branch information...
commit 59f883badf6321b4e841cb3b7336de7dc02b783a 1 parent 2aafdce
@josevalim josevalim authored
View
17 README.rdoc
@@ -31,10 +31,11 @@ if you want to make a contact form just the following lines are needed (includin
Then you start a script/console and type:
c = ContactForm.new(:name => 'José', :email => 'jose@email.com', :message => 'Cool!')
- c.deliver
+ c.create
-Check your inbox and the e-mail will be there, with the sent fields (assuming
-that you configured your mailer delivery method properly).
+The delivery will be triggered in an after_create callback. So check your inbox
+and the e-mail will be there, with the sent fields (assuming that you configured
+your mailer delivery method properly).
==== MailForm::Resource
@@ -115,8 +116,7 @@ Examples:
c.errors.full_messages #=> [ "Name can't be blank", "Email is invalid" ]
c = ContactForm.new(:name => 'José', :email => 'your@email.com')
- # save is an alias to deliver
- c.save #=> true
+ c.deliver #=> true
==== subject(string_or_symbol_or_block)
@@ -210,9 +210,10 @@ is an I18n example file:
models:
contact_form: "Your site contact form"
attributes:
- email: "E-mail"
- telephone: "Telephone number"
- message: "Sent message"
+ contact_form:
+ email: "E-mail"
+ telephone: "Telephone number"
+ message: "Sent message"
errors:
messages: :"activerecord.errors.messages"
request:
View
8 lib/mail_form.rb
@@ -1,8 +1,8 @@
-require 'active_model'
-
class MailForm < ActionMailer::Base
- autoload :DSL, 'mail_form/dsl'
- autoload :Resource, 'mail_form/resource'
+ autoload :Callbacks, 'mail_form/callbacks'
+ autoload :DSL, 'mail_form/dsl'
+ autoload :Resource, 'mail_form/resource'
+ autoload :Shim, 'mail_form/shim'
self.template_root = File.expand_path('../views', File.dirname(__FILE__))
View
23 lib/mail_form/callbacks.rb
@@ -0,0 +1,23 @@
+module MailForm::Callbacks
+ def self.extended(base)
+ base.class_eval do
+ include ActiveSupport::Callbacks
+ define_callbacks :create, :terminator => "result == false", :scope => [:kind, :name]
+ end
+ end
+
+ def before_create(*args, &block)
+ set_callback(:create, :before, *args, &block)
+ end
+
+ def around_create(*args, &block)
+ set_callback(:create, :around, *args, &block)
+ end
+
+ def after_create(*args, &block)
+ options = args.extract_options!
+ options[:prepend] = true
+ options[:if] = Array(options[:if]) << "!halted && value != false"
+ set_callback(:create, :after, *(args << options), &block)
+ end
+end
View
2  lib/mail_form/dsl.rb
@@ -55,7 +55,7 @@ def attribute(*accessors)
case validation
when Symbol, Class
validate validation
- return
+ break
when Regexp
validates_format_of accessor, :with => validation, :allow_blank => true
when Array
View
60 lib/mail_form/resource.rb
@@ -1,10 +1,6 @@
class MailForm::Resource
- extend ActiveModel::Naming
- extend ActiveModel::Translation
- include ActiveModel::Validations
- include ActiveModel::Conversion
-
- extend MailForm::DSL
+ include MailForm::Shim
+ extend MailForm::DSL
ACCESSORS = [ :form_attributes, :form_subject, :form_captcha,
:form_attachments, :form_recipients, :form_sender,
@@ -13,8 +9,10 @@ class MailForm::Resource
class_inheritable_reader *ACCESSORS
protected *ACCESSORS
+ before_create :not_spam?
+ after_create :deliver!
+
# Initialize arrays and hashes
- #
write_inheritable_array :form_captcha, []
write_inheritable_array :form_appendable, []
write_inheritable_array :form_attributes, []
@@ -27,18 +25,6 @@ class MailForm::Resource
attr_accessor :request
- # Initialize assigning the parameters given as hash (just as in ActiveRecord).
- #
- # It also accepts the request object as second parameter which must be sent
- # whenever :append is called.
- #
- def initialize(params={}, request=nil)
- @request = request
- params.each_pair do |attr, value|
- self.send(:"#{attr}=", value)
- end unless params.blank?
- end
-
# In development, raises an error if the captcha field is not blank. This is
# is good to remember that the field should be hidden with CSS and shown only
# to robots.
@@ -64,37 +50,13 @@ def not_spam?
!spam?
end
- # Always return true so when using form_for, the default method will be post.
- #
- def new_record?
- true
- end
-
- # Always return nil so when using form_for, the default method will be post.
- #
- def id
- nil
+ # Deliver the resource checking if it's valid? and not_spam?
+ def deliver
+ create
end
- # If is not spam and the form is valid, we send the e-mail and returns true.
- # Otherwise returns false.
- #
- def deliver(run_validations=true)
- if !run_validations || (self.not_spam? && self.valid?)
- MailForm.deliver_default(self)
- return true
- else
- return false
- end
+ # Deliver the resource without checking any condition.
+ def deliver!
+ MailForm.deliver_default(self)
end
- alias :save :deliver
-
- def self.i18n_scope
- :mail_form
- end
-
- def self.lookup_ancestors
- super - [MailForm]
- end
-
end
View
49 lib/mail_form/shim.rb
@@ -0,0 +1,49 @@
+require 'active_model'
+
+# This the module which makes any class behave like ActiveModel.
+module MailForm::Shim
+ def self.included(base)
+ base.class_eval do
+ extend ActiveModel::Naming
+ extend ActiveModel::Translation
+ include ActiveModel::Validations
+ include ActiveModel::Conversion
+
+ extend MailForm::Callbacks
+ extend MailForm::Shim::ClassMethods
+ end
+ end
+
+ module ClassMethods
+ def i18n_scope
+ :mail_form
+ end
+ end
+
+ # Initialize assigning the parameters given as hash (just as in ActiveRecord).
+ def initialize(params={})
+ params.each_pair do |attr, value|
+ self.send(:"#{attr}=", value)
+ end unless params.blank?
+ end
+
+ # Always return true so when using form_for, the default method will be post.
+ def new_record?
+ true
+ end
+
+ # Always return nil so when using form_for, the default method will be post.
+ def id
+ nil
+ end
+
+ # Create just check validity, and if so, trigger callbacks.
+ def create
+ if valid?
+ _run_create_callbacks { true }
+ else
+ false
+ end
+ end
+ alias :save :create
+end
View
11 test/notifier_test.rb
@@ -7,7 +7,8 @@ def setup
@request = ActionController::TestRequest.new
@valid_attributes = { :name => 'José', :email => 'my.email@my.domain.com', :message => "Cool\nno?" }
- @advanced = AdvancedForm.new(@valid_attributes, @request)
+ @advanced = AdvancedForm.new(@valid_attributes)
+ @advanced.request = @request
test_file = Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__), 'test_file.txt'))
@with_file = FileForm.new(:name => 'José', :email => 'my.email@my.domain.com', :message => "Cool", :file => test_file)
@@ -160,14 +161,6 @@ def test_form_with_file_does_not_output_attachment_as_attribute
assert_no_match /File:/, ActionMailer::Base.deliveries.first.body
end
- # For some reason, this test does not fail in Rails 3.
- #
- # def test_form_with_customized_template_raise_missing_template_if_not_found
- # assert_raise ActionView::MissingTemplate do
- # @template.deliver
- # end
- # end
-
def test_form_with_customized_template_render_correct_template
begin
default_template_root = MailForm.template_root
Please sign in to comment.
Something went wrong with that request. Please try again.