Error when trying to link to patient profile - ruby-on-rails

I'm getting an error when trying to link_to a patient profile when a provider views his patients list. I have no problem displaying all the names of the patients that belong to the provider but when trying to link to the patient profile I get an undefined method 'id'.
So the way it works is, patients can search for providers and add them to the List model. On the provider side, I just list out all the patients that added that specific provider. Here is my erb code below,
<div class="body">
<div class="body">
<% if #active_patients.count > 0 %>
<table>
<thead>
<tr>
<th>Patient Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% #active_patients.each do |list| %>
<tr>
<td>
<%= list.patient.role.user.first_name %> <%= list.patient.role.user.last_name %>
</td>
<td>
<%= link_to patient_path(id: #patient.id), class: "btn" do %>View<% end %> . #### THIS IS THE LINE
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div class="no-records">
<%= image_tag "icon-no-records", class: "image" %>
<div class="text">You have no patients.</div>
</div><!--no-records-->
<% end %>
</div><!--body-->
</div>
Here is my List model,
class List < ApplicationRecord
belongs_to :membershipable, :polymorphic => true
belongs_to :provider
def patient
membershipable_type=='Patient' ? membershipable : nil
end
def provider_user
patient.try(:user)
end
end
Also here's the error message ->

Let Rails do the work of building the path. Each ActiveRecord model has a to_param method which decides how the instance will be encoded in an URL. By default it returns the model id but it could also be a slug based on the title or another property of the model.
Calling your helper like patient_path(patient) should do the trick.
Additionally, in your current code, you're referring to the previously unused #patient variable, even though it looks like you want to refer to list.patient instead.

Here:
<% #active_patients.each do |list| %>
<tr>
<td>
<%= list.patient.role.user.first_name %> <%= list.patient.role.user.last_name %>
</td>
<td>
<%= link_to patient_path(id: #patient.id), class: "btn" do %>View<% end %> . #### THIS IS THE LINE
</td>
</tr>
<% end %>
you have the variable list available to you. It appears that you get the patient by doing list.patient, as you do here:
<%= list.patient.role.user.first_name %> <%= list.patient.role.user.last_name %>
But, then you try to use a variable called #patient, here:
<%= link_to patient_path(id: #patient.id), class: "btn" do %>View<% end %> .
when you don't have the variable #patient. So, you get your nil error.
Instead, it seems you should do:
<%= link_to patient_path(id: list.patient.id), class: "btn" do %>View<% end %> .
Or, as milgner points out, you could simply do:
<%= link_to patient_path(list.patient), class: "btn" do %>View<% end %> .
Also, you might want to look into the Law of Demeter, which you violate (IMO) when you do:
list.patient.role.user.first_name

Related

How to get an array of values from a group of checkbox in Ruby on Rails?

I'm new to Rails and I don't understand how to solve this problem.
I've got 2 entities: Player and Call Up; N:M relationship. So basically a call up has an id, some attributes (like opponents, date...) and a list of players.
In the new call up's form i added a table of players that could be included. Each row has checkbox with the corresponding player id. Here's the view:
<%= form_with(model: call_up) do |form| %>
<!--Call Up Informations-->
<!---->
<table class="table">
<thead>
<tr>
<th colspan="5"></th>
</tr>
</thead>
<tbody>
<% #players.each do |player| %>
<tr>
<td><%=player.first_name %></td>
<td><%=player.last_name %></td>
<td><%=player.number %></td>
<td><%=player.role %></td>
<div class="field">
<td><%=form.check_box :player_ids, class: "form-check-input", value: player.id %></td>
</div>
</tr>
<% end %>
</tbody>
</table>
<br>
<div class="actions text-center">
<%= form.submit "Create Call Up", class: "btn btn-dark" %>
</div>
<% end %>
In the controller i tried to get the player ids array by using params[:player_ids] but it produce a nil error.
Can anyone help me out?
Sometime digging the source code help us a lot, especially when the guide is not clear. Take a look at all check_box params
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).
end
Here your form.check_box under a form_with of an object so the object_name is that object name call_up, method here is what object params you want to post player_ids, checked_value and unchecked_value are the values of that params when user submit the form, they will be send as an alternative checked/unchecked array of each checkbox [0, 1, 0, 1, ...], if you just want to send only checked values, just set unchecked_value = nil.
<td><%=form.check_box :player_ids, {multiple: true, skip_default_ids: false, class: "form-check-input"}, player.id, nil %></td>
One more thing, your controller will receive the has params object_name => {..., method: [...]}, so you need to permit that array:
def call_up_params
params.require(:call_up).permit(:name, player_ids: [])
end
Here you can do multiple checkboxes and better user expererience/interface when they tap or click on player id, the checkbox will be checked. Just make sure you have player_ids: [] included in the strong parameters of call_ups_controller.rb, also you should have #players = Player.all variable in call_ups controller or instead you can just use Player.all.each do |player|. Also why not use a form_for instead?
# In case you end up creating a partial file and you want to render it as a partial, make sure you uncomment the hidden field below.
# You can also use this for edit view.
#<%= hidden_field_tag "call_up[player_ids][]", nil %>
<% #players.each do |player| %>
<div class="form-check">
<%= check_box_tag "call_up[player_ids][]", player.id, #call_up.player_ids.include?(player.id), id: dom_id(player), class: 'form-check-input' %>
<%= label_tag dom_id(player), class: 'form-check-label' do %>
<%= player.id %>
<% end %>
</div>
<% end %>

how can i get project_id by remarks in ruby on rails

I have manager remark model that takes input as a remark and decision value and saves it with the project site ID. I have a project site model that takes input as name, date, and file and stores it. Many remarks have a many to one relation with project site ID, and the project site belongs to the manager remark. I want to access the decision attribute boolean value in project site index form, but I am unable to access that boolean value in the index page of the project site. Here is my code of project site and manager remarks model, view and controller-
project site index.html.erb
<table>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Attendance</th>
<th>Status</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #project_sites.each do |project_site| %>
<tr>
<td><%= project_site.name.titleize %></td>
<td><%= project_site.date %></td>
<td><%= link_to ' View attendance', project_site.file, :class => "fi-page-export-csv" %></td>
<td><%= "here i want to access manager remark decision value" %></td>
<td><%= link_to 'Remark ', project_site %><span>(<%= project_site.manager_remarks.size %>)</span></td>
<td><%= link_to 'Edit', edit_project_site_path(project_site) %></td>
<td><%= link_to 'Destroy', project_site, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
project site controller
def index
#project_sites = ProjectSite.all.order("created_at DESC")
#manager_remark = ManagerRemark.joins(:project_site).where(:project_sites => { :user_id => #user.id })
end
# GET /project_sites/1
# GET /project_sites/1.json
def show
#manager_remark = ManagerRemark.new
#manager_remark.project_site_id = #project_site.id
end
# GET /project_sites/new
def new
#project_site = ProjectSite.new
end
def project_site_params
params.require(:project_site).permit(:name, :date, :file)
end
manager_remark controller
class ManagerRemarksController < ApplicationController
def create
#manager_remark = ManagerRemark.new(remark_params)
#manager_remark.project_site_id = params[:project_site_id]
#manager_remark.save
redirect_to project_site_path(#manager_remark.project_site)
end
def remark_params
params.require(:manager_remark).permit(:remark, :decision)
end
end
manager_remark view form
<%= form_for [ #project_site, #manager_remark ] do |f| %>
<div class="row">
<div class="medium-6 columns">
<%= f.radio_button :decision, true %>
<%= f.label :approve %>
<%= f.radio_button :decision, false %>
<%= f.label :reject %>
</div>
<br>
<br>
<div class="medium-6 cloumns">
<%= f.label :remark %><br/>
<%= f.text_area :remark %>
</div>
</div>
<div>
<%= f.submit 'Submit', :class => 'button primary' %>
</div>
<% end %>
routes.rb
Rails.application.routes.draw do
root to: 'home#index'
devise_for :users
resources :project_sites do
resources :manager_remarks
end
get '/project_manager_level_two' => 'project_manager_level_two#index'
get '/project_managers' => 'project_managers#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
If I understand correctly, you have a ProjectSite that contains a ManagerRemark with a decision, right? If that's the case, the simple answer is:
<%= project_site.ManagerRemark.decision %>
If you are saying that each ProjectSite has many ManagerRemarks, you'll want to place the above inside a loop, like so:
<% project_site.manager_remarks.each do |manager_remark| %>
<%= manager_remark.decision %><br/>
<% end %>
This assumes that your models are correctly configured to recognize these relationships. The above may also be optimized by adding an include clause to your fetch inside the controller and there's no need to fetch the ManagerRemark objects separately. Therefore, you'd probably want something like:
def index
#project_sites = ProjectSite.all.includes( :manager_remark ).order("created_at DESC")
end

How to result and validate associated data from multiple Table cells

Example: 2 tables
Table 1:
"Orders"
cells:
-id
-etc
-etc
Table 2:
"Sales_uploads"
cells:
-id
-order_id (same data as "id" in Orders table)
-etc
-etc
I have created =
Order.where(id: Sales_upload.pluck(:order_id))
from Googling, but haven't figured out where to go from here.
I have this def in my sales_upload model:
def order_sales_relationship
Order.where(id: Sales_upload.pluck(:order_id))
end
Then in the views I have: (a portion of views)
<% #orders.each do |order| %>
<tbody>
<tr>
<td class="center"><%= order.buyer.name %></td>
<td class="center"><%= number_to_currency(order.listing.price) %></td>
<td class="center"><%= order.created_at.strftime("%B %-d, %Y") %></td>
<td class="center">
<div class="field">
<% if #order_sales_relationship = true %>
<%= link_to '/sales' %>
<% else %>
<%= link_to "Upload", new_order_sales_upload_path( order, #order ), class: "btn btn-primary" %>
<% end %>
When i use this, '/sales' appears in the upload section of the table even if nothing has been uploaded. I believe the model is incorrect and may jst be validating if the cells exist, but not validating if they also match. How would i validate the matching as wlel (if this is even true)
The goal is to display an upload link ONLY if the upload hasn't happened yet. If it has, I want only an update/edit link (which is '/sales' atm as a placer, that's a whole other issue).
ok from what I'm understanding, please correct me
change
def order_sales_relationship
Order.where(id: Sales_upload.pluck(:order_id))
end
to
def order_sales_relationship
#order_sales = Order.where(id: Sales_upload.pluck(:order_id))
end
in view make this changes
<% if #order_sales.present? %>
and
<%= link_to "Upload", new_order_sales_upload_path(order, #order), class: "btn btn-primary" %>
??? where is #order

Dynamic checkbox with Ajax in Rails

I have a Form with some checkboxes loaded from the Database, and an option to add other items manually to the items table. This is done by Ajax in the code below...
item_controller.rb
def manual_item_add
#manual_item = Item.find(params[:id_item].to_i)
respond_to do |format|
format.js
end
end
manual_item_add.js.erb
$("#items_table").append("<%= escape_javascript(render 'manual_item_add', :manual_item => #manual_item) %>")
_manual_item_add.html.erb
...
<td><%= check_box_tag("manual_items[]", item.id, true) %></td>
...
edit_items.html.erb
<%= form_tag( {controller:"item", action:"edit_items"}) do %>
<p align="center">
<%= select_date(#account.start_date, prefix: 'start_date') %>
to
<%= select_date(#account.end_date, prefix: 'end_date') %>
</p>
<%= hidden_field_tag 'id_account', #account.id %>
<table id="items_table" class="subtable" align="center" width="55%">
....
<tr>
<th colspan="6">Items added manually</th>
</tr>
<tr>
<th># ID</th>
<th>Type</th>
<th>Description</th>
<th>Ammount</th>
<th>Date</th>
<th>Include in the account</th>
</tr>
</table>
<p align="center"><%= submit_tag("Save", class: "btn") %></p>
<% end %>
<%= form_tag( {controller:"item", action:"manual_item_add"}, method:"get", remote: true) do %>
<h4 align="center">Add item manually</h4>
<p align="center">Item ID:
<%= text_field_tag "item_id", nil , size:5, maxlength:5 %>
<%= submit_tag("Add Item", class: "light_btn") %>
</p>
<% end %>
So... the problem here is that though I see the new checkboxes i am adding to the table (they are being created normally), the "manual_items[]" array is not being passed to the controller when I submit the resulting form (by the way, the "items_table" is inside the form definition).
Does anybody know what I am doing wrong? Sorry for the newbie question, I'm starting to work with Ruby + Rails.
Unfortunately, I don't have a definitive answer for this problem. The only working solution I've tried was to use JQuery to force parameters to be part of the form:
$(document).ready(function() {
$("#edit_items_form").submit(function(event) {
$(this).append($("input[name='manual_items[]']:checked"));
$(this).submit();
});
});
I am definitely not comfortable to this solution, I'd like to know why these Ajax checkboxes are not automatically recognized as being part the form.

Ruby on Rails field_for Form Helper Problems

I'm using the field_for form helper with a loop:
<% f.fields_for :permissions do |permission_form| %>
<tr>
<td><%= permission_form.object.security_module.name %><%= permission_form.hidden_field(:security_module_id) %></td>
<td><%= permission_form.object.security_module.description %></td>
<tr>
<% end %>
The resulting output of the above code is this:
<input id="role_permissions_attributes_0_id" name="role[permissions_attributes][0][id]" type="hidden" value="76" />
<tr>
<td>Diary<input id="role_permissions_attributes_0_security_module_id" name="role[permissions_attributes][0][security_module_id]" type="hidden" value="13" /></td>
<td>Access to the Diary Module</td>
</tr>
<!-- next input field then <tr> tag -->
The problem with this markup is that the input tag falls outside of the tr tag which there for causes validation issues with XHTML.
Does anyone know how I can have the input tag fall inside the tr tag therefore giving me valid XHTML 1.0 STRICT markup?
Thanks
If you take a look at the Rails source code you'll find this.
# in actionpack/lib/action_view/helpers/form_helper.rb
def fields_for_nested_model(name, object, args, block)
if object.new_record?
#template.fields_for(name, object, *args, &block)
else
#template.fields_for(name, object, *args) do |builder|
#template.concat builder.hidden_field(:id)
block.call(builder)
end
end
end
Notice it is adding the hidden field directly here, and it doesn't look like there is any option to change this behavior. The easiest thing is probably to create your own custom form builder.
# in lib/no_id_form_builder.rb
class NoIdFormBuilder < ActionView::Helpers::FormBuilder
private
def fields_for_nested_model(name, object, args, block)
#template.fields_for(name, object, *args, &block)
end
end
And then use this in your form. You'll need to add the id field manually.
<% f.fields_for :permissions, :builder => NoIdFormBuilder do |permission_form| %>
<tr>
<td>
<%= permission_form.object.security_module.name %>
<%= permission_form.hidden_field(:security_module_id) %>
<%= permission_form.hidden_field(:id) unless permission_form.object.new_record? %>
</td>
<td><%= permission_form.object.security_module.description %></td>
<tr>
<% end %>
You may want to submit a lighthouse ticket on this. perhaps there could be a :skip_id_field option to fields_for which does this.
There is a workaround available as of 2.3.5. If you explicitly place the :id field, it won't implicitly add it for you:
<% form_for #foo do |f| %>
<table>
<tbody>
<% f.fields_for :bars do |bf| %>
<tr>
<td>
<%= bf.hidden_field :id %>
<%= bf.text_field :name %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
See
https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3259
Slight correction:
The :builder option needs to go on the form_for containing the fields_for, not the fields_for.

Resources