How should I approach making a custom form involving different model attributes? - ruby-on-rails

I'm rather new to Ruby, so I need guidance as how to approach this. I know how to make very simple forms, but I'm thinking of implementing a custom form that can generate a payroll for a business during a specific start and end date. I already have business and payroll models, but I'm not sure how to implement this type of custom form and properly route it to get it be fully functional. Are there any resources or pieces of guidance I can get to help me with this?

please checkout this link :create an application on RoR. Please go to the link above and get started by creating your very own application. I have started with this and have learned a lot from this. This will get you kick started on RoR. But I believe you need more guidance in Ruby also. So I am attaching some more useful links. Please check them out also.
tutorails point - ruby
ruby-lang documentation
ruby guides
Thank you.

I don't know if I really get your issue... If your models Business and Payroll are linked (with :belongs_to and :has_many) you should check the fields_for method. You can nest it in a form_for/form_with to create fields associated to an other model. For instance you can do something like that:
#in your view
<%= form_with model: #business |f| %>
<%= f.label "Something:" %>
<%= f.text_field :something %>
<%= f.fields_for #business.payroll do |ff| %>
<%= ff.label "Something else:" %>
<%= ff.text_field :something_else %>
<% end %>
<%= f.submit %>
<% end %>
#in your controller
if #business.create(business_params)
#...
end
if #business.payroll.create(payroll_params)
#...
end
Hope it will help you !

Related

How can I create a button which adds fields to a Rails form

I have a form in Rails which uses fields_for to accept nested attributes:
<%= form_with(model: #combat_tracker, url: form_url) do |f| %>
…
<%= f.fields_for :zones do |zone| %>
<div class="zone-field">
<%= zone.text_field :name %>
<%= zone.check_box :_destroy %>
<%= zone.label :_destroy, "Remove zone" %>
</div>
<% end %>
…
<% end %>
Currently this gives me input fields for any existing zones on #combat_tracker. I want to add a button that will dynamically add a new zone-fields div for a new zone to be added when the form is submitted.
I’m using Rails 7 and assume the solution will involve the use of Turbo or possibly Stimulus, but can’t quite figure out the best way to do this. Thanks.
I don't think you need Turbo or Stimulus. Take a look at cocoon gem, it should do exactly what you're looking for.
Explaining all process here is quite complex for me, but try to follow this guide if the gem's one is too long.

Nested forms using the Cocoon gem in Ruby on Rails 4.2

I'm building a web app using Rails 4.2 and I have a model called Strategy which has a has_many relationship to a Tactic model.
To create a view for Strategy, I need to have many nested Tactics on the form. I've been using the Cocoon gem to develop this view.
So far, I've been able to get the form to work properly for the most part but the issue is that I wanted to add a Type attribute to my Tactic model.
For a given strategy, I want to have 3 tactics of one given type, and 2 models of another.
The issue is that rendering my view, all five models are listed sequentially without any room for putting in my own HTML code around them.
Is there a simple way to separate out which of these are rendered? Right now, my view looks as follows...
<%= form_for #strategy do |f| %>
<div class="strategy">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="tactics">
<%= f.fields_for :tactics do |i| %>
<%= render 'tactics_fields', f: i %>
<% end %>
</div>
<div class="buttons">
<%= f.button "Save Strategy", class: 'button' %>
</div>
<% end %>
If anyone can offer any advice, it would be greatly appreciated.
Are you wanting the form to be rendered so that each Strategy has exactly 5 Tactics listed below it, of which 3 are of one type and 2 are of another?
If so, you can do this in your controller:
5.times do
tactic = #strategy.tactics.build
tactic.tactic_type = 'tactic_type'
end
Also, note that using an attribute called type is not a good idea. Use something like tactic_type instead.

Building Form Based On an Association in Rails

I am very new to rails and having a bit of a problem with a simple page I am putting together for learning and I was hoping someone might have some suggestions on a fix or a better approach.
Essentially, I have the concept of a scratch pad. Each pad has_many tasks and has_many notes. In the pad's show, I want to have two independent forms. One for adding tasks and one for adding notes. The problem is, I build the forms like so:
<%= form_for([#pad, #pad.tasks.build]) do |f| %>
<%= f.text_field :text %> <%= f.submit %>
<% end %>
Now, since I've called .build, when I later call the below code to render the tasks it always renders an additional, empty record in the list.
<ul>
<%= render #pad.tasks %>
</ul>
I thought about using a nested form, but this seems to require me to use PadsController::Update rather than TasksController:Create like I want to.
What would be the appropriate approach in this situation? Being so new to rails (started yesterday), I'm afraid I'm missing something obvious.
Edit: I added the source to a github repository. As I said, this is just a learning project for me. https://github.com/douglinley/scratchpad
If you simply want a new task without it being added to #pad.tasks collection, I believe you can just do #pad.tasks.new instead of #pad.tasks.build (which does add it to the collection).
For more on build vs new, check out
Build vs new in Rails 3
So, this was much easier than I thought. Instead of calling new on the collection, I just created a new object for the form. Example below:
<%= form_for([#pad, Task.new]) do |f| %>
<%= f.text_field :text %> <%= f.submit %>
<% end %>

Does Ruby on Rails have an equivalent to Django's ModelForm?

I have been using Django for about a year and thought I would try Ruby on Rails to see how it compares. In Django, you can create a ModelForm that automatically generates a html for based on the types of fields in your model. Is there a class that does something similar in Rails? I know scaffolding will generate a erb file for my model, but is there a way to do this?
<%= auto_form_for #person %>
Or this?
<%= form_for #person do |f| %>
<% for each #person.fields do | field| %>
<%= auto_field f, field %>
<%end%>
<% end %>
I apologize for my poor ruby code.
Formtastic implements the Django pony magic you're looking for, and most variants thereof that might actually be useful. In my opinion, most end-user apps don't find "auto forms" and scaffolds to be very useful (since they so often need to be customized in detail), but Formtastic may output enough semantic HTML for you to style in a way that works for your users.
Rails also allows you to write your own custom form builders; you can also extend the ones Formtastic provide.
I found a gem called simple_form that is similar to formtastic. It allows you to to define forms like this:
<%= simple_form_for #user do |f| %>
<%= f.input :username %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
I've used it for a few projects, and it's worked out great. It also has integration with twitter bootstrap, if you are using that library.

how to handle multiple models in a rails form

http://weblog.rubyonrails.org/2009/1/26/nested-model-forms
This post helped in learning how to handle multiple models in a rails form. It works as long as the models are nested. what if they are not? lets say, I have a form, where the user fills personal details, address details and a bunch of checkboxes specifying her interests. There are at least 3 tables involved in this one single form, what is the best way to handle this, without having 3 different save buttons?
Two options:
First is ActivePresenter which works well for this.
Second is just to use fields_for:
<%= form_for #user do |f| %>
<%=f.label :name %>
<%=f.text_field :name %>
<%= fields_for #address do |fa| %>
<%=fa.label :city %>
<%=fa.text_field :city %>
<% end %>
<% end %>
Then in the controller, save the records.
#user = User.new(params[:user])
#address = Address.new(params[:address])
ActivePresenter works so well though.
Also found a railsforum post via Google, which would work well.
You can refer this tutorial by The Pragmatic Programmers
Advanced Rails Recipes

Resources