Build rails form fields from associated models - ruby-on-rails

Rails3,jQuery. What I'm trying to do: Create a new WorkoutPlan that HABTM Exercises. Then create a new Workout that belongs_to a WorkoutPlan. I want the Workout#edit page to build a form with fields_for new/edit WorkoutRoutines, one routine for each exercise in the WorkoutPlan.
That last part is where I'm struggling, creating one Routine for each Exercise in the WorkoutPlan. Everything else works, its just this form build that sucks. Not sure if I'm making this overly complicated, or if there was an easier way. Any ideas?

From what I understand, using nested attributes should solve the problem without many complications. From the link,
Nested attributes allow you to save
attributes on associated records
through the parent. By default nested
attribute updating is turned off, you
can enable it using the
accepts_nested_attributes_for class
method. When you enable nested
attributes an attribute writer is
defined on the model.
The attribute writer is named after
the association, which means that in
the following example, two new methods
are added to your model:
author_attributes=(attributes) and pages_attributes=(attributes).

anytime you need a complex form in rails its either going to be a pain, or can use formtastic. super easy awesome forms, plenty of ways to deal with habtm relations as well.

Related

Edit models with complex primary key with Active Admin

I'm having a trouble with opening AA edit-page for a model, which has a lot of associations.
What I had it's like 50 selects, opening at once. And this page turns to be deadly slow.
After reading this ActiveAdmin: How to handle large associations I considered to use select2 instead of usual select, but things get even worse.
That was because most of the time Rails spent in generating views, not in querying database. So with fancy select2 it reasonably spends even more time in views.
With that knowledge in mind, I decided to not have select inputs on that page at all. So I'll edit "main" object on that slow page, but connected with has_and_belongs_to_many objects should be edited separately.
But after that decision I've faced with a trouble: how should I edit tables with a complex primary key: not just id, but :person_id and :organization_id.
AA by default generates urls like that: /admin/person_organizations/:id/edit, but I need something like this: /admin/person_organizations/:person_id/:organization_id/edit
Any ideas?
ActiveAdmin should be able to handle custom primary keys by default. Just be sure that you add the definition to your model like this:
class Person < ActiveRecord::Base
self.primary_key = 'person_id'
end
After a while I've decided that I don't even need to have multiple keys here since Rails generates artificial id field for habtm tables. And as my goal was to edit this table, I've finished with standard ways of doing this.

Submitting two tables/model data with single/two form on one webpage with single submit button?

My issue is simple, lets say I have two models/tables named 'abc' and 'pqr', both has three columns as 'a','b','c' in abc and 'p','q','r' in pqr. This two models may or may not be related/nested.
what I want to do is to create a single webpage. On that webpage I want to create a single form which will submit the data for two models/table with single button. May be I will create two form but I want only one submit button. How do solve this issue in ruby on rails.
As in rails we have one model per table.
You can only use accepts_nested_attributes_for if the two models are related. Otherwise, if the models are unrelated, see Anton's answer in rails: a single simple_form with two unrelated models? describing how to use the fields_for helper to accomplish this.
I can suggest you something in Ruby side. It is possible to do that with accepts_nested_attributes_for method.
You can add to
models/abc.rb
accepts_nested_attributes_for :pqr
You can find more information about it here.
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Reform to wrap a collection of records to be saved simultaneously

I have a collection of records that are related to a specific parent object. I have no need to update the parent, just want to update all the children.
I tried making a Reform::Form and simply adding the collection declaration. An example might be a developer has many projects. When the developer goes on holiday his projects are "on_hold", but some of them might still be active. So, I would like to list all the projects with a checkbox to check if they should be put on hold. I essentially want to have a simple_fields_for :projects.
Does it make sense to use Reform for this?
I have this code:
class ProjectsForm < Reform::Form
collection :projects do
property :name #perhaps I want to rename them in the same form (bear with me)
property :on_hold
end
end
This should work, but when initializing the form with a hash
#form = ProjectsForm.new({projects: #array_of_projects})
I get an error
undefined method `projects' for #<Hash:0x007fce8f2783b8>
As if the collection method is not working. I am obviously doing something stupid.
I'd really like to use Reform. I love the philosophy behind a lot of the trailblazing suit of gems. It will be great if someone can point me in the right direction here.
If it turns out this isn't a good usecase for Reform I'll find another :P
Update:
I think reform is slightly more coupled with the idea of a model than what I thought. I thought it was just a form object with properties to play nicely with form builder. I now find that your model is key. You need to initialize the Reform form with A model, or in the case of composition, a few models. However, if you pass in an array of hash reform believes this is the model and then tries to access the :projects property on the model. In my case a hash.
I have now added a
# my contrived example is getting lame
attr_accessor :projects
to the developer class and it is working. At least the generating the reform object is working.
I am still curious wether this is a good use-case for Reform.

In a single form, linking two instances of two models with habtm

I am using Rails 3.
I have a Product model and a Group model (a group has_many users, through membership).
I would like to build the new.html.erb form for the product model, and at the end of the form, I would like the user to be able to choose members from which group(s) can have access to the product he wants to add.
So, my goal is to list the groups to which the user belongs to, adding a checkbox for each of them. Then, create the associations between the product inserted and the different groups the user selected when the form is submitted, but I really do not understand how to achieve this, as all the documentation I have read use the BUILD or CREATE method that defines a new instance of group, instead of an existing one.
Is it possible with a nested form, and a HABTM relationship between product and group ? Or should I use a nested form with a has_many_through association using new model product_group_relationship ? Or should I use something else than a nested form ?
I'm quite new in Rails and a little bit lost here, so if some experienced guy could guide me a little bit, it would be very much appreciated!
The form_for helper comes with a nice package of extra methods like: fields_for wich makes you able to add nested attributes for has_many_through relations.
I suggest reading these:
http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for
And make sure you set your model validations accordingly

Creating forms for relational data in Rails

I have a form that I need to display for a table that has a relationship with a couple of other tables. For instance, I have a table "cases" (think, investigator case), that has_one claimant and has_one client.
I would like the form to display the fields to fill out for the case data, client data and claimant data. Is there an easy way to do this so that when it's submitted, it would be as simple as:
case = Case.new(params[:case])
case.save
As it would be if I was just submitting and saving a form for only the case data?
Sounds like you are looking for the accepts_nested_attributes_for method of activerecord. You will need to craft your form using
- form.fields_for :claimant do |claimant_form|
= claimant_form.text_field :name
You can find much more information in Ryan Daigle's blog post
I don't believe there's a way where you can just call case.save and it'll work.
To make the form, look into using fields_for. http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#M001605
fields_for allows you to add fields that are stored in different POST variables, so if you set up the fields correctly then in your new method you could potentially do something like this:
claimant = Claimant.new(params[:claimant])
claimant.save
Which isn't terribly more complicated.
See my complex-form-examples on creating nested multi-model forms. This has been updated to work with Rails 2.3's accepts_nested_attributes_for.
It allows you to nest the associations all under params[:case] like you want. When you call case.save everything else will be saved too.

Resources