Created
February 8, 2015 07:02
-
-
Save brainwire/a8ae7f3fb152f3a3187b to your computer and use it in GitHub Desktop.
Coocon: Allow to use with simple arrays without AR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| I'm using my branch now in the project which works perfectly fine so far. | |
| The only additional glue to use it with fully transient models are those few methods: new_record?, marked_for_destruction? and _destroy. | |
| I'm not sure why cocoon touches the _destroy method. | |
| The example above allows using fully transient models (non-ActiveRecord) with cocoon and any form builder. | |
| I'll put everything together for a comprehensive example: | |
| Model: | |
| Requirements are: | |
| all objects must be ActiveModel-compliant (eg, plain ActiveModel, Virtus, ActiveAttr etc) | |
| implement the new_record?, marked_for_destruction? and _destroy methods on the nested object | |
| implement build_<nested_name> (as in, build_user) to return a new template | |
| implement <nested_nameS>_attribtues= (as in, users_attribtues=) to parse the POSTed data and update the nested items appropriately. | |
| Full implementation: | |
| class User | |
| include ActiveAttr::Model | |
| attribute :email | |
| end | |
| class Company | |
| include ActiveAttr::Model | |
| attribute :name | |
| def users | |
| @users ||= [] | |
| end | |
| def users_attributes=(attrs) | |
| @users = attrs.map { |key, params| User.new(params) } | |
| end | |
| def build_user | |
| User.new # blank state for new template | |
| end | |
| def new_record? | |
| true | |
| end | |
| def marked_for_destruction? | |
| false | |
| end | |
| def _destroy | |
| false | |
| end | |
| end | |
| Views | |
| The view will look like a regular one that uses ActiveModel (in my case, it's a simple form builder): | |
| = simple_form_for @company, as: :company, url: company_path(@company), method: :put do |f| | |
| = f.input :name | |
| %h2 Users | |
| = link_to_add_association '+', f, :users , 'data-association-insertion-node' => '#users', 'data-association-insertion-method' => 'append' | |
| #users | |
| = f.simple_fields_for :users, @company.users do |user_form| | |
| = render 'user_fields', f: user_form | |
| where user_fields may look like: | |
| %h3 User details | |
| f.input :name | |
| = link_to_remove_association "X", f | |
| ____ | |
| <% @server.interfaces.each do |interface| %> | |
| <div> | |
| <%= f.fields_for :interfaces, OpenStruct.new(interface), index: "" do |interface_form| %> | |
| <%= render "interface_fields", f: interface_form %> | |
| <% end %> | |
| </div> | |
| <% end %> | |
| ____ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment