From 2a493390d9906c3496713bf3cbccc5a5d5bba0a1 Mon Sep 17 00:00:00 2001 From: Kir Shatrov Date: Sun, 19 Oct 2014 16:30:57 +0200 Subject: [PATCH] Samples and tests for Plain Old Ruby Objects with feedback demo --- README.md | 51 ++++++++++++++++++++++++++++++--- test/forms/poro_form_fixture.rb | 14 +++++++++ test/forms/poro_form_test.rb | 41 ++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 test/forms/poro_form_fixture.rb create mode 100644 test/forms/poro_form_test.rb diff --git a/README.md b/README.md index d43487b..8447cf1 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,9 @@ Consider an example where you want to create/update a conference that can have m ```ruby class ConferenceForm < ActiveForm::Base self.main_model = :conference - + attributes :name, :city - + validates :name, :city, presence: true end ``` @@ -223,11 +223,11 @@ Use `fields_for` in a Rails environment to correctly setup the structure of para <%= form_for @conference_form |f| %> <%= f.text_field :name %> <%= f.text_field :city %> - + <%= f.fields_for :speakers do |s| %> <%= s.text_field :name %> <%= s.text_field :occupation %> - + <%= s.fields_for :presentation do |p| %> <%= p.text_field :topic %> <%= p.text_field :duration %> @@ -323,6 +323,49 @@ And `app/views/conferences/_presentation_fields.html.erb` would be: ``` +## Plain Old Ruby Object Forms + +ActiveForm also can accept `ActiveModel::Model` instances as a model. + +Let's define the Feeback class class with `ActiveModel::Model` that will be used for customer's feedback: + +```ruby +class Feedback + include ActiveModel::Model + + attr_accessible :name, :body, :email + + def save + FeedbackMailer.send_email(email, name, body) + end +end +``` + +The form should look like this. + +```ruby +class FeedbackForm < ActiveForm::Base + attributes :name, :body, :email, required: true +end +``` + +And then in controller: + +```ruby +class FeedbacksController + def create + feedback = Feedback.new + @feedback_form = FeedbackForm.new(feedback) + @feedback_form.submit(feedback_params) + + if @feedback_form.save + head :ok + else + render json: @feedback_form.errors + end + end +``` + ## Demos You can find a list of applications using this gem in this repository: https://github.com/m-Peter/nested-form-examples . diff --git a/test/forms/poro_form_fixture.rb b/test/forms/poro_form_fixture.rb new file mode 100644 index 0000000..411d525 --- /dev/null +++ b/test/forms/poro_form_fixture.rb @@ -0,0 +1,14 @@ +class Poro + include ActiveModel::Model + + attr_accessor :name, :city + + def save + true + end +end + +class PoroFormFixture < ActiveForm::Base + self.main_model = :conference + attributes :name, :city, required: true +end diff --git a/test/forms/poro_form_test.rb b/test/forms/poro_form_test.rb new file mode 100644 index 0000000..cf7ab5d --- /dev/null +++ b/test/forms/poro_form_test.rb @@ -0,0 +1,41 @@ +require 'test_helper' +require_relative 'poro_form_fixture' + +class PoroFormTest < ActiveSupport::TestCase + include ActiveModel::Lint::Tests + + setup do + @poro = Poro.new + @form = PoroFormFixture.new(@poro) + @model = @form + end + + + test "main form validates itself" do + params = { + name: "Euruco", + city: "Athens" + } + + @form.submit(params) + + assert @form.valid? + + @form.submit({ name: nil, city: nil }) + + assert_not @form.valid? + assert_includes @form.errors[:name], "can't be blank" + assert_includes @form.errors[:city], "can't be blank" + end + + test "save works" do + params = { + name: "Euruco", + city: "Athens" + } + + @form.submit(params) + + assert @form.save + end +end