Skip to content

Commit

Permalink
Add Form#attributes_with_values and support dashes in param keys
Browse files Browse the repository at this point in the history
  • Loading branch information
andypike committed Mar 29, 2017
1 parent 6e1ec65 commit 7a9fc99
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ GIT
PATH
remote: .
specs:
rectify (0.8.0)
rectify (0.9.0)
activemodel (>= 4.1.0)
activerecord (>= 4.1.0)
activesupport (>= 4.1.0)
Expand Down
1 change: 1 addition & 0 deletions lib/rectify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require "rectify/version"
require "rectify/form"
require "rectify/form_attribute"
require "rectify/format_attributes_hash"
require "rectify/build_form_from_model"
require "rectify/command"
require "rectify/presenter"
Expand Down
6 changes: 5 additions & 1 deletion lib/rectify/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def self.from_params(params, additional_params = {})

convert_indexed_hashes_to_arrays(attributes_hash)

new(attributes_hash)
new(FormatAttributesHash.new.format(attributes_hash))
end

def self.convert_indexed_hashes_to_arrays(attributes_hash)
Expand Down Expand Up @@ -93,6 +93,10 @@ def attributes
super.except(:id)
end

def attributes_with_values
attributes.reject { |attribute| public_send(attribute).nil? }
end

def map_model(model)
# Implement this in your form object for custom mapping from model to form
# object as part of the `.from_model` call after matching attributes are
Expand Down
26 changes: 26 additions & 0 deletions lib/rectify/format_attributes_hash.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Based on http://stackoverflow.com/questions/8706930/converting-nested-hash-keys-from-camelcase-to-snake-case-in-ruby

module Rectify
class FormatAttributesHash
def format(params)
convert_hash_keys(params)
end

private

def convert_hash_keys(value)
case value
when Array
value.map { |v| convert_hash_keys(v) }
when Hash
Hash[value.map { |k, v| [underscore_key(k), convert_hash_keys(v)] }]
else
value
end
end

def underscore_key(k)
k.to_s.underscore.to_sym
end
end
end
2 changes: 1 addition & 1 deletion lib/rectify/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Rectify
VERSION = "0.8.0".freeze
VERSION = "0.9.0".freeze
end
87 changes: 55 additions & 32 deletions spec/lib/rectify/form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@
expect(form.contacts[2].number).to eq("789")
end

it "converts param keys with dashes to underscores" do
params = ActionController::Parameters.new(
"id" => "1",
"user" => {
"first-name" => "Andy"
}
)

form = UserForm.from_params(params)

expect(form.first_name).to eq("Andy")
end

it "populates an indexed array of attributes" do
params = ActionController::Parameters.new(
"user" => {
Expand Down Expand Up @@ -135,36 +148,6 @@

expect { form.some_extra_data }.to raise_error(NoMethodError)
end

context "when a model is explicitally mimicked" do
it "returns the matching model name" do
expect(ChildForm.model_name.name).to eq("User")
end
end

context "when a model is not explicitally mimicked" do
describe "#model_name" do
it "returns the class name minus the `Form` suffix" do
expect(OrderForm.model_name.name).to eq("Order")
end

it "returns the class name minus the `Form` suffix and namespace" do
expect(Inventory::ProductForm.model_name.name).to eq("Product")
end
end

it "uses the class name minus the `Form` suffix as the params key" do
order_params = {
"order" => {
"number" => "12345"
}
}

form = OrderForm.from_params(order_params)

expect(form.number).to eq("12345")
end
end
end

describe ".from_model" do
Expand Down Expand Up @@ -249,8 +232,32 @@
end

describe ".model_name" do
it "allows a form to mimic a model" do
expect(UserForm.model_name.name).to eq("User")
context "when a model is explicitally mimicked" do
it "returns the matching model name" do
expect(ChildForm.model_name.name).to eq("User")
end
end

context "when a model is not explicitally mimicked" do
it "returns the class name minus the `Form` suffix" do
expect(OrderForm.model_name.name).to eq("Order")
end

it "returns the class name minus the `Form` suffix and namespace" do
expect(Inventory::ProductForm.model_name.name).to eq("Product")
end
end

it "uses the class name minus the `Form` suffix as the params key" do
order_params = {
"order" => {
"number" => "12345"
}
}

form = OrderForm.from_params(order_params)

expect(form.number).to eq("12345")
end
end

Expand Down Expand Up @@ -296,6 +303,22 @@
end
end

describe "#attributes_with_values" do
it "returns a hash of attributes where their values are non-nil" do
form = AddressForm.new(
:id => 1,
:street => "1 High Street",
:town => nil,
:post_code => "GU1 2AB"
)

expect(form.attributes_with_values).to eq(
:street => "1 High Street",
:post_code => "GU1 2AB"
)
end
end

context "when being used with a form builder" do
describe "#to_key" do
it "returns an array containing the id" do
Expand Down

0 comments on commit 7a9fc99

Please sign in to comment.