One Model without nested Form Rails - ruby-on-rails

I have only one user model, I want to give add more option on the form.
There are many example have nested form but in my case no need to nested because I have only one user model.
I want to save bulk of users using add more form

You can do something like:
<%= form_tag users_path do %>
<% #users.each do |user| %>
<%= fields_for 'users[]', user do |u| %>
<div class="field">
<%= u.label :name %><br>
<%= u.text_field :name %>
</div>
<% end %>
<% end %>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>
def create
params[:users].each do |user|
# create
end
end

Related

rails: how to update multiple records using "accepts_nested_attributes"

Let's say I have a cat model and a life model. And let's say a cat (#cat) has_many lives, and a cat accepts_nested_attributes for a life.
Now, if I wanted to update 7 lives (#lives) at once, using one form_for(#cat), how would that form look like? This is what I've tried, but in this form only the attributes for the last life are passed to the params hash:
<%= form_for(#cat) do |f| %>
<% #lives.each do |life| %>
<%= f.fields_for(life) do |l| %>
<%= l.input :date_of_birth, as: :date %>
<% end %>
<% end %>
<%= f.submit %>
<% end %>
You need to build the attributes in your controller
#cat = Cat.find(<criteria>)
#cat.lives.build
In your example, you have a loop inside a loop. Try this:
<%= form_for(#cat) do |f| %>
<%= f.fields_for(:lives) do |l| %>
<%= l.input :date_of_birth, as: :date %>
<% end %>
<%= f.submit %>
<% end %>

Change checkbox to change in db in rails?

I have a table "User" with "admin" is "true" or "false". I show it with checkbox_feild. How can i change db if i clicked in checkbox? Thanks all.
<% #users.each do |user| %>
<%= form_for user, do |f| %>
<div class="field">
<%= f.check_box :admin%>
</div>
<% end %>
<% end %>
One way is to write a jquery script that submits the form when checkbox is clicked
<% #users.each do |user| %>
<%= form_for user,:html => {class: 'form'} do |f| %>
<div class="field">
<%= f.check_box :admin%>
</div>
<% end %>
<% end %>
Jquery script would be:
$('.form input[type=checkbox]').change(function(){
$(".form").submit();
});

Processing two unassociated Rails models' forms in one controller action

I'm creating a Rails app that will take in input from two models and their respective forms, and then log into a website with Mechanize and do hundreds of tasks there.
The first form consists of the user's login information (the username and password, using the model User), and the second one is a long list of term names and their respective definitions (using the model Term and uploaded into the form as an Excel doc).
I have no need to associate these two models (unlike in similar SO questions, which seem to deal with nested models). Once this Mechanize task completes, I will destroy both models' objects from the database.
The two pieces of the app (logging in to the website; and uploading the terms and using them to interact with the website) both work perfectly in separate scripts.
My question is: How can I take in both models' information on one webpage and coordinate the controller(s) accordingly? In this situation, can I create both objects in one controller? (If not, that's fine, as long as there's an alternative; I'm game for whatever will get this to work.)
I'm posting some of my code below. I'm happy to answer any questions you may have. Please keep in mind I am pretty new at Rails, so is not very elegant code:
The User model:
class User < ActiveRecord::Base
attr_accessor :username, :password
end
And the Term model:
class Term < ActiveRecord::Base
attr_accessible :name, :definition
end
In my terms controller (the forms are located in the index action and the script is run in the show action):
def create
#term = Term.new(params[:term])
#user = User.new(params[:user])
if (#term.save && #user.save)
flash[:notice] = "Your terms have been sent for processing."
redirect_to terms_path
else
render :action => 'index'
end
end
def show
#term = Term.all
agent = Mechanize.new
page = agent.get('www.myurl.com')
#log into the website
#user.username = myform.field_with(:id => "userfield").value
#user.password = myform.field_with(:id => "passfield").value
#and then enter the term information into the website's forms
rest of Mechanize code goes here...
end
And in views/terms/index.html.erb:
#the login form:
<%= render 'loginform' %>
#the term file uploader:
<%= form_tag import_terms_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
<br>
<table id="terms">
<tr>
<th>Name</th>
<th>Definition</th>
</tr>
#displays the uploaded terms on the index page
<% #terms.each do |term| %>
<tr>
<td><%= term.name %></td>
<td><%= term.definition %></td>
</tr>
<% end %>
</table>
<p><%= link_to 'Update website with these terms', terms_update_terms_path %></p>
And in views/terms/_loginform.erb:
<%= form_for(#user) do |f| %>
<div class="field">
<%= f.label_tag(:username, 'Username') %><br />
<%= f.text_field_tag(:user, :username) %>
</div>
<div class="field">
<%= f.label_tag(:password, 'Password') %><br />
<%= f.password_field_tag(:user, :password) %>
</div>
<% end %>
And in views/terms/_termform.html.erb
<%= form_for(#term) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :definition %><br />
<%= f.text_area :definition %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
If you just need to save the data and truly don't want to associate the models, I would save the Term separately:
<%= form_for #user do |f| %>
<div class="field">
<%= f.label :username, 'Username' %>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= label_tag :name %>
<%= text_field_tag :name %>
</div>
<div class="field">
<%= label_tag :definition %>
<%= text_field_tag :definition %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Then in your controller:
#term = Term.new
#term.attributes = {
:name => params[:name],
:definition => params[:definition]
}
#term.save
If you are adding multiple term fields to the form, I would consider something like Cocoon, and just add an each loop for saving the Terms in the controller.

Ruby on Rails, instead of update make new entry to model

I made a simple demo site, with an model for the patients name (name:string) and another model with the treatment (content:text). I created this "project" to learn more about the accepts_nested_attribute for tag and the fields_for tag.
Now my problem is that on the patient show page i created an nested formula for the treatment , like you can see here:
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #patient.name %>
</p>
<ol>
<% for treatment in #patient.treatments %>
<li><%= treatment.content %></li>
<% end %>
</ol>
<%= form_for(#patient) do |f| %>
<%= f.fields_for :treatments do |builder| %>
<div class="field">
<%= builder.label :content %><br />
<%= builder.text_field :content %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Edit', edit_patient_path(#patient) %> |
<%= link_to 'Back', patients_path %>
So my problem is that in the builder.text_field :content better called the input shows up the last saved treatment from <%= builder.content %>, but i want that he does not update it instead i want to add new treatments! Hopefully somebody understands me! Thanks
I would create separate controller for creating only the treatment, eg.
# treatments_controller.rb
class TreatmentsController < ApplicationController
def create
#patient = Patient.find(params[:patient_id])
#treatment = #patient.treatments.new(params[:treatment])
if #treatment.save
redirect_to #patient
else
# handle unsuccessful treatment save
end
end
end
# routes.rb:
resources :patients do
resources :treatments, only: :create
end
# form:
<%= form_for #patient, #treatment do |f| %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You should also set #treatment variable in the patient#show action, like this:
#treatment = #patient.treatments.new

Rails Nested Attributes Doesn't Insert ID Correctly

I'm attempting to edit a model's nested attributes, much as outline here, replicated here:
<%= form_for #person do |person_form| %>
<%= person_form.text_field :name %>
<% for address in #person.addresses %>
<%= person_form.fields_for address, :index => address do |address_form|%>
<%= address_form.text_field :city %>
<% end %>
<% end %>
<% end %>
In my code, I have the following:
<%= form_for(#meal) do |f| %>
<!-- some other stuff that's irrelevant... -->
<% for subitem in #meal.meal_line_items %>
<!-- # Edit 2: I need to display information here about the subitem
Which I can't find a way to pass it to the partial, or work in
this manner for existing items
-->
<%= subitem.food.name %>
<%= subitem.food.calories %>
<%= f.fields_for subitem, :index => subitem do |line_item_form| %>
<%= line_item_form.label :servings %><br/>
<%= line_item_form.text_field :servings %><br/>
<%= line_item_form.label :food_id %><br/>
<%= line_item_form.text_field :food_id %><br/>
<% end %>
<% end %>
<%= f.submit %>
<% end %>
This works great, except, when I look at the HTML, it's creating the inputs that look like the following, failing to input the correct id and instead placing the memory representation(?) of the model. As a result, an update fails:
<input type="text" value="2" size="30" name="meal[meal_line_item][#<MealLineItem:0x00000005c5d618>][servings]" id="meal_meal_line_item_#<MealLineItem:0x00000005c5d618>_servings">
EDIT:
The reason I'm attempting to do it in this method is that I need to gather some information on associations for existing meal_line_items. For example, in the area where I took out code, I have some code to the effect of:
<%= subitem.food.name %>
<%= subitem.food.calories %>
Getting this information won't work if I am using a form builder with partials, at least, not in my trials.
Edit 2:*
See the edit in the code. Here's my MealLineItem
class MealLineItem < ActiveRecord::Base
# Associations ---------------------
belongs_to :food
belongs_to :meal
end
And meal accepts_nested_attributes for the model. As you can see it belongs to both food and meal model. For the existing meal_line_item I need to do something like:
meal_line_item.food.name
Is there f. missing from <%= fields_for?
--edit
Have you tried:
<%= f.fields_for 'meal[meal_line_item][]', subitem do |line_item_form| %>
--edit
Docs say that it should work without loop too:
<%= form_for(#meal) do |f| %>
<!-- some other stuff that's irrelevant... -->
<%= f.fields_for :meal_line_items do |line_item_form| %>
<%= line_item_form.label :servings %><br/>
<%= line_item_form.text_field :servings %><br/>
<%= line_item_form.label :food_id %><br/>
<%= line_item_form.text_field :food_id %><br/>
<% end %>
<%= f.submit %>
<% end %>
Have to test this but maybe this approach?
_form
<%= form.fields_for :meal_line_items do |meal_line_item_form| %>
<% #meal.meal_line_items.each do |meal_line_item| %>
<%= render :partial => "meal_line_items/meal_line_item", :locals => { :meal_line_item_form => meal_line_item_form, :meal_line_item => meal_line_item } %>
<% end %>
<% end %>
meal_line_items/_meal_line_item.erb
<%= meal_line_item_form.label :servings %><br/>
<%= meal_line_item_form.text_field :servings %><br/>
<%= meal_line_item_form.label :food_id %><br/>
<%= meal_line_item_form.text_field :food_id %><br/>
EDIT
here's a link to an example for setting the formbuilder iterator directly (Rails 2.3.8 though). The associations between Outbreak -> Incidents -> Location should be similiar to the ones for Meal -> Meal_line_items -> Food.
AJAX update of accepts_nested_attributes_for partials
After searching high and low, I found the error. Although I was modifying the partial and was receiving a NameError it's because I was calling the partial from a helper method - exactly the same problem as stated in the following question:
rails fields_for render partial with multiple locals producing undefined variable

Resources