Display a blank form Rails - ruby-on-rails

I'm newbie in Rails and I'm developing an app that needs to display a patients info in a form to be updated by a doctor if needed. As soon I can select a patient from a list from sidebar I want to display first just an empty form and when a patient is selected all the info will be displayed on it.
The only way I can guess to do it is to first display the form empty and then, once the patient is selected, catch the patient on the controller and reload the page to allow the form to get the patient info.
Does anybody has a better idea? On negative answer: how can I display an empty form?
Thanks in advance for your time.
Best regards.
Update: This is the form I'm trying to present on the page. #patient is an instance variable that once the page is displayed is not defined yet . It will be displayed once the doctor will select one patient from a list on the side.
<div class="row">
<div class="span6">
<%= render 'shared/error_messages' %>
<div>
<%= form_for(#patient) do |p| %>
<%= text_field_tag 'patient[name][]', nil, :placeholder => "name", :style =>height:12px;font-size:10px;" %>
<%= text_field_tag 'patient[name][]', nil, :placeholder => "surname", :style =>"height:12px;font-size:10px;" %>
<%= p.text_field :email, :placeholder => "email", :style => height:12px;font-size:10px;" %>
<%= p.text_field :phone, :placeholder => "phone", :style => height:12px;font-size:10px;" %>
<%= check_box_tag :active %>
<%= check_box_tag :sex, 'male' %>
<%= check_box_tag :sex, 'female' %>
<%= chack_box_tag :dao %>
<%= p.submit "Sumbit", class: "btn btn-small btn-primary pull-right", id: "boton" %>
<% end %>
</div>
</div>
</div>
An here is the problem. As #patient=nil on the controller since on is selected page crashes.
Thanks again.

What you are describing here are basic controller actions on your model:
Empty Form: #new action on Patients controller
Filled Form: #edit action on Patients controller
Edit: New Strategy to Accomplish Your Proposed UX
Component 1: Nav List of Existing Patients
Iterate over collection of patient objects, outputting a link for each patient to its edit view: link_to patient.name, edit_patient_path(patient)
This nav view will be a partial that you will include in the view templates for the PatientsController #new action and #edit action.
Component 2: Empty Form for Nonexistent/New Patient
In controller new action, instantiate a new Patient object, like so #patient = Patient.new.
Render the patient form on that #patient instance variable, as you do in the view code above.
Include the nav list of existing patients as a view partial.
Component 3: Filled Form for Existing Patient
In controller edit action, instantiate the Patient instance variable, like so #patient = Patient.find(params[:id]).
Render the patient form on that #patient instance variable, as you do in the view code above.
Include the nav list of existing patients as a view partial.
Edit: Old Points on Scaffolding
I would strongly suggest using rails generators and scaffolding to set up basic forms and view templates, at least as an educational pursuit. You will, via the command line, be able to automatically generate the proper controller actions and view templates you are describing above for #new and #edit.
Read this article: http://viget.com/extend/rails-3-generators-scaffolding
Then follow this tutorial: http://railscasts.com/episodes/216-generators-in-rails-3
As you become more comfortable with Rails development, generators and scaffolding will likely not satisfy you and needs for customization. They are, however, a great starting point.
See also: http://guides.rubyonrails.org/getting_started.html#getting-up-and-running

I think, one more option is you can Instantiate your object on your form itself:
<%= form_for(Patient.new) do |p| %>
Thanks

Related

rails form data entered in the first field is not saved, but is saved when link_to add_nested is used

I'll try to ask this as clearly as I can. I'm doing a Udemy course and we are using nested fields to take in data. The form renders a single nested field initially and then there is a link to add additional fields. This all works and there are no errors in the console. If i put something in the first nested field, and add two more nested fields, only what was entered in the last two nested fields gets saved. When I look at the final result after saving, the first item is not there. I'm sure this has to do with how I'm rendering the initial field, but I can't figure out what it is. Both the initial render and the link_to_add_nested are using the same partial file.
Screenshot of the form
Code from _form.html.erb:
<div>
<%= form_with model: #technologies do |form| %>
<%= render partial: 'technology_fields', :locals => { :form => form } %>
<% end %>
</div>
<div>
<%= link_to_add_nested(form, :technologies, '#Add-Technology', partial: 'technology_fields') %>
</div>
<div class="form-group">
<%= form.submit "Save Portfolio Item", class: 'btn btn-primary btn-block'%>
</div>
<% end %>
</div>
Code from the partial _technology_fields.html.erb:
<div class="form-group nested-fields" id=Add-Technology>
<%= form.label :name %>
<%= form.text_field :name, class: 'form-control' %>
<%= link_to_remove_nested(form, link_text: 'Remove Item') %>
</div>
I can add code from the models and controller if needed, but as the form is working with the dynamically added nested fields, I don't think that's where the problem lies.
Bonus question: The same form is used for new and edit actions. Ideally when the form is used to edit an existing item, I would like the page to render with fields populated with the existing data. As it currently stands I have no way to delete or modify once it has been saved. I can only add new entries.
Thank you very much for any help you can give. I've done a lot of searching but haven't been able to locate the right information.

How to determine button id in another view depending on a different view Rails

I'm making an app where some activities are listed in a table called Fakultety (polish language, sorry), and participants on in another table called Uczestnicy.
I have a submit form where you can submit yourself to an activity, but I'm stuck on passing values to a DB. Firstly, I don't know how to tell to the database on which activity you want to be assigned to (I tried to change the submit button id to an activity id and then passing it into a database but don't know how to do this id: "#{#fakultet.id}" not working) and later I want to count how many people are assigned to field participants in a database Fakultety, but I don't want to pass all the data, just ID of the users from table called Uczestnicy. How to do it? I mean just to pass the ids to another table, and how to tell the database on which activity I want to be assigned to?
This is my form view:
<h1>Zapisujesz sie na fakultet</h1>
<div class="form-group">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#participant, url: zapisy_path) do |f| %>
<p>Imię:</p>
<%= f.text_field :firstName, class: 'form-control' %>
<p>Nazwisko:</p>
<%= f.text_field :lastName, class: 'form-control' %>
<p>Grupa:</p>
<%= f.text_field :group, class: 'form-control' %>
<%= f.submit "Zapisz się", class: "btn btn-primary" id: "#{#fakultet.id}"%>
<% end %>
</div>
</div>
</div>
Does anybody understand me and can help me?
Rails provides form collection helpers that make it really easy to assign associations:
# I'm going to just do this in english
<%= form_for(#activity) do |f| %>
<%= f.collection_select(:participant_ids, Partipicant.all, :id, :name, prompt: true, multiple: :new) %>
# ...
<% end %>
Then whitelist the attribute as an array:
params.require(:activity).permit(:foo, :bar, participants_ids: [])
Thats all you actually need to assign childen to to a parent resource. This is done as a part of the normal create/update actions of the parent resource.
You don't actually need the form for the child records unless you actually want to be creating the record. In that case you can setup a nested resource or if you want to create/edit multiple nested records at the same time as the parent record you can use nested attributes.
First you should rename your models and tables, to English, it's a really bad pattern to use your language, in English it is easier to understand by other devs.
According to the problem, probably what you are looking for is hidden_field
<%= f.hidden_field :fakultet_id, :value => #fakultet.id %>
and if you want to query Fakultety that have user assigned, you can select Fakultety where participant_id is not nil
Fakultety.where.not(participant_id: nil)

Update two non-associated models with one submit button, using nested form

I have a User controller that possesses the two following records:
user.vehicles from VehiclesController
user.trip_distances from TripDistancesController
In the Vehicles view, I need to display and update both models (Vehicle and TripDistance)
I figured out that I need to use a nested form. However, I don't understand how to implement it since my #trip_distances record needs a loop in order to display all of its content.
First, I tried to put this in the Vehicle model, but since both are NOT linked, I wonder if this is correct:
accepts_nested_attributes_for :trip_distances, allow_destroy: true
Then, in the Vehicle view's _form file, during the edit action, I have:
<%= form_for(#vehicle) do |f| %>
I need to put my nested form inside it. Here's what I got so far:
<% #trip_distances.each do |t| %>
<%= f.fields_for t do |fields| %>
<div class="field">
<%= fields.text_field :id_contract %>
<%= fields.number_field :length %>
</div>
<% end %>
<% end -%>
My trip_distances records are correctly displayed, but the unique Submit button doesn't work anymore. I'd like to update both model while clicking on one button. What am I missing?
I was able to make it work by associating the two models. Then I use the following fields_for tag:
<%= f.fields_for :trip_distances do |builder| %>
My submit button is now working, but the :trip_distances fields are not updated, I don't know why.

Rails - Multiple forms, different Models (Objects), one submit button

I have a view with 3 forms, Schedules, Workouts and Exercises, all behaving like an edit form, each. And one submit(save) button in the all the view.
When I click on the save button. Every data changed on those forms should be updated after click.
What is the best solution for this ? Javascript updating each data separated ? How to do that ? Is there a more Rails way to do this easily ?
My difficulty is how to integrated all those models in one view, while all this is happening in the show(view) from the Student model.
If you're implementing something like a profile / edit page (where you can save all the records at once), the two ways I would look at would either be to save the forms via Ajax, or use a single submit method to handle them
Ajax
The ajax method would be the most conventional:
Every form you submit will go to the form's own update method in the backend
Each form could be handled by a single button, but it's best to split them up
#app/controllers/profile_controller.rb
def edit
#schedules = Schedule.all #-> not sure how many records you're using
#workouts = Workout.all
#exercises = Exercise.all
end
#app/views/profile/edit.html.erb
<%= form_for #schedule do |f| %>
<%= f.text_field :test %>
<% end %>
# -> other forms
<%= button_to "Save", "#", id: "save" %>
#app/assets/javascripts/application.js
$("#save").on("click", function() {
$("form").submit(); // we'll have to define the form to submit
});
Single
If you submit all the forms as one, you'll have to encase them all in a single form, as sending different errors. This could be achieved by using _, and handled in the backend by looping through the different params, saving each one individually.
I'd do this:
#app/controllers/application_controller.rb
def submit
types = %w(schedules exercises workouts)
for type in types do
type.constantize.update_attributes()
end
end
This allows you to create a form with the different data types submitted in the same action:
#app/views/profile/edit.html.erb
<%= form_tag profile_submit_path do %>
<%= fields_for #schedules do |f| %>
<%= f.text_field :title %>
<% end %>
# -> fields_for for the other objects
<% end %>
This will allow you to send the updated objects to your controller, allowing them to submit
If all of your models (Schedules, Workouts and Exercises) are associated, using fields_for should be a good option.
From the above link:
<%= form_for #person do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
<%= fields_for :permission, #person.permission do |permission_fields| %>
Admin? : <%= permission_fields.check_box :admin %>
<% end %>
<%= f.submit %>
<% end %>
Read the guides.
You could have some simple javascript that iterates over all form tags and submits each of them.
Alternatively, if you are going to use javascript anyways, you could follow an AJAXish auto-save approach upon changing any field.
But I think it might be cleaner if you just had one form for multiple models, using fields_for.

How to select current model in a 3 model system?

I have 3 models. Users have multiple Portfolios and Portfolios have multiple Assets.
When a user signs in, that makes him a current_user by find_by_id. When they first register, it creates a portfolio for them. That becomes the current_portfolio.
Subsequent to this, they can create portfolios which redirects them to the list of all their portfolios. Clicking the link to each will make that portfolio the current_portfolio.
#current_portfolio = current_user.portfolios.find_by_id(params[:id])
The show view for portfolios has an assets form so that they can quickly add assets to the portfolio. This is where I get stuck. Because the assets form is on the portfolios show view, my Asset controller needs to reference current_portfolio, but this is in my Portfolio controller.
Portfolio Controller:
def show
#current_portfolio = current_user.portfolios.find_by_id(params[:id])
#asset = #current_portfolio.assets.build
end
When the form is submitted, it goes to my Assets controller Create function. Create can't simply have #current_portfolio because it's on a different controller. I also can't use find_by_id(params[:id]) because :id is not providing anything.
How do I reference the second model when I have 3 models? (Sorry I'm a newb to rails...)
EDIT Update: I thought I found the solution but realized it didn't work.
I passed <%= hidden_field_tag :portfolio_id, params[:id]%> in my form and set my Create in the Asset controller to be
def create
#asset = Asset.new(params[:asset])
#asset.save
end
but it's not getting the portfolio_id which is a required field in my model.
Full form in my view
<%= form_for(#asset) do |f| %>
<%= hidden_field_tag :portfolio_id, params[:id]%>
<%= f.text_field :asset_symbol %>
<%= f.text_field :shares %>
<%= f.text_field :cost %>
<%= f.text_field :purchase_date, :type=>'date' %>
<%= f.submit "+ Add to Portfolio" %>
<%end%>
My guess would be that the portfolio_id in the hidden field isn't coming back as part of the asset hash. Maybe it's as simple as assigning the #asset.portfolio_id = params[:portfolio_id] before the save. Check you logs to see EXACTLY what is coming back in the POST

Resources