Creating multiple items with a single creation workflow - ruby-on-rails

I'm trying to create multiple items (associated classes) from the parent class to the very child one (4 level deep) in a single workflow. I'd like to be able to create the parent item, then click on "next" to be able to create one/many children, then click on "next" to create the children of the children, and so on... Finally, in the last screen, i'd like to be able to save all the items by clicking on save. If something is missing in the child item, the parent class cannot be created as well.
Do we have any ideas of how i can manage to do that?
Many thanks :)

You can use accepts_nested_attributes_for in the parent model to associate the child models,.
In the view you can use fields_for or simple_fields_for (if simple_form gem is used) to list the child model fields in the subsequent steps,.
In every step rather than saving the object in the db, you can check if the object is valid or not using .valid? instead of save. At the final step you can use .save method.
With .valid? you can get the errors at each step and at the final step you can save all the records by creating the parent object.

Related

Rails show parent data in child index page

See the code and what I mean in the picture
how do i show the parent in the child index page?
An example is the ID number 1,2,3,5 they are the child and their parent is the account name OSCAR. and for the parent THIRD their ID child number is 6 and 7.
I can show the child in the parent show page but I dont know how to display them oppositely.
like this is working if my parent want to display child
but I want a child index showing all the child and with its parents
This looks like a Data integrity issue to me. Open a rails console with rails c and then type Remittance.find_by(id: 4).invoice, it will either be that is nil as the objects aren't properly associated, or Remittance.find(id: 4).invoice.account_name will be "" or nil, as that invoice's account_name doesn't have anything populating it.
EDIT:
To fix the problem:
You need to associate your database objects in the model with a has_many/belongs_to relationship. With a SQL DB, this is done with a foreign key. Here's the documentation: http://guides.rubyonrails.org/association_basics.html

Eager load grandchild attribute without child in rails

In Rails, I'm trying to eager load something to speed it up. I've got a Parent-Child-Grandchild situation, but only need the Parent and an attribute of the Grandchild. If I...
Parent.all.includes(:child => :grandchild)
then Bullet gripes about an unused eager load of the child (which is true, I don't need it). Is there an easier way to have access to the Parent record and Grandchild.some_attribute?
A couple options...
1) Cache the value of the grand-child (denormalize the db, add a column and store the attribute) on the parent. Do this if there is only one grandchild and you want to frequently show this value in a situation where you have many parents.
2) can you do a has_many :through on the grandchildren? Then you can just do an include(:grandchildren). That may save generating the child objects.
3) If it really is child and grandchild (has_ones, or belongs_to), you can probably find a simple way to do a query (or scope) on grandchild based on the parent id. You can then run two queries, one to get parent.all, one to get grandchild.grandchild_of(parents.map(&:id)), and then loop in ruby and add the attribute to the parent as a attribute, ready for use when you loop through the parents later.
4) Lastly, do a specific, hand worked sql query to select the parent attributes and the grandchild.attribute. The attribute will be attached to the parent and accessible by parent.grandchild_attribute_name. Parent.select('parents.*, grandchild.attribute').joins(:grandchild). This you'll need to experiment with, depending on your model.

Dynamic linking gets cleared when inserting new records

I have one form in AX 2012 from which i am calling another child form which shows records that are related to the selected record in Parent form(Dynamic linking).
Now, when I am trying to create a new record in a child form, the dynamic linking between this form and its parent form gets cleared and child form starts showing all data according to its datasource and not any filtered records which I don't want.
I want to know that, how to get stick with that dynamic linking while creating new Record in a child form.
Check that your grids really belongs to the correct datasources. If not, strange things happen.

Can't grab foreign key during after_create callback because it doesn't exist yet!

I have some models all linked together in memory (parent:child:child:child) and saved at the same time by saving the top-most parent. This works fine.
I'd like to tap into the after_create callback of one of the children to populate a changelog table. One of the attributes I need to copy/push into the changelog table is the child's foreign_key to it's direct parent, but it doesn't exist at the time after_create fires!?!
Without the after_create callback, I can look in the log and see that the child is being saved before it's parent (foreign key blank) then the parent is inserted... then the child is updated with the id from the parent. The child's after_create is firing at the right time, but it happens before Rails has had a chance to update the child with the foreign_key.
Is there any way to force Rails to save such a linkage of models in a certain order? ie.parent, then child (parent foreign_key exists), then that child's child (again, foreign_key is accessible) etc. ?? If not, how would I have my routine fire after a record is created AND get the foreign_key?
Seems a callback like this would be helpful: after_create_with_foreign_keys
Since I was building all my associated models in memory and relying on Rails to save everything when I saved the top-most parent, I couldn't tap into the after_create callbacks and utilize a foreign key (for a change_log table entry) because of the order in which Rails would save the models. Everything always ended up connected in the proper way, but sometimes a child record would be saved first, then the parent, then an update to the child record to insert the parent_id would happen.
My solution was to not build my models in memory, abandoning the idea of saving everything in one fell swoop. Instead, I would save the top-most model and then create its child via the after_create of that parent. That child's after_create would then create its child and so on. I like this arrangement much better as I have more control over my callbacks in relation to foreign keys. Lastly, the whole thing was wrapped in a db transaction so as to undo any inserts if something went horribly wrong along the way. This was my original reason for building everything in memory, so I'd have all my ducks in a row before saving. Model/db transactions alleviates the worry.
Could you use after_update to catch the child after the parent_id is available? When after_update fires, the parent_id will be available, so if the child is not in the table, insert it.

Setting default values across multiple children in a multi model form (Rails 2.3 )

Am trying to simplify the create / edit view for a multi-model controller.
User can dymically add / remove child input fields from the form. (Have followed Eloy's complex form example)
I want to limit the user's ability to set certain attributes across multilpe children..
Suppose I have a child attribute with and I want the user to only input the date once.. eg the date will be the same across all children..
I would like present a single date entry box and then multiple Adults | Seniors boxes depending on the number of children the user wants to submit.
using accepts_nested_attributes_for my form is showing multiple date boxes..
(Since I want to retain the ability to do this as an admin I don't want to move the date attribute to the parent.)
How should I go about adapting the form without having to extend the controller logic too much?
If you have business logic that states that all of your children models have the same date, then I see this working a couple different ways.
First of all, maybe you have your data in the wrong place. If the date is always going to be the same for all of the children models, then why not make it an attribute on your parent model instead? You can always use the delegate method in your children model to fetch the date from the parent.
Another way I see of handling this is with a virtual attribute and a callback on your parent model. Use attr_accessor to create a virtual attribute on your parent model. Then in your form, add a field for the date to the parent model with the name you used to define the attr_accessor. Finally, add in a before_save callback (or whichever callback is appropriate for your case) in the parent model that saves the date to all of the children.

Resources