-
Notifications
You must be signed in to change notification settings - Fork 35
Samples and tests for Plain Old Ruby Objects with feedback demo #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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: | |
| </div> | ||
| ``` | ||
|
|
||
| ## 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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You also need to set
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK the PR with auto-detection of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right you are 😄 |
||
| 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 . | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not override save 😄
What do you think of this?
(I also changed the mailer so it's closer to the actual Action Mailer API in Rails 4.2.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActiveModel::Modeldoesn't have any save method or callbacks by default.