How to iterate over multiple hash values with Espinita in Rails - ruby-on-rails

I am using Espinita to keep track of changes to my model and have multiple attributes that I would like to display in the view.
I haven't figured out how to iterate over each value without using an || in the iterator. I want to get the attribute name, the changed value and the date.
This is show.html:
<% #contract.contract_information.history_from_audits_for([:contract_title, :assigned_to, :action_requested..:deadline]).each do |changes| %>
<tr>
<%= changes[:contract_title] || changes[:assigned_to] || changes[:deadline] %>
<%= changes[:changed_at].strftime("%m/%d/%Y") %>
</tr>
<% end %>
How do I iterate over each audit without referencing the attribute name?
UPDATE
After making the recommended changes. I now receive the attributes/values in array form. Is there a way to beautify the results in the view?
Output
11/20/2019 [:contract_stage, ""] [:action_requested, ""] [:reason_for_contract_request, ""] [:existing_or_returning, ""] [:background_check_status, ""] [:priority, ""] [:deadline_date, Wed, 20 Nov 2019] [:commencement_date, Wed, 20 Nov 2019] davie200
View
<% #contract.contract_information.history_from_audits_for([:contract_stage, :action_requested, :reason_for_contract_request, :deadline_date, :commencement_date, :existing_or_returning, :background_check_status, :priority]).each do |audit| %>
<% audit.except(:changed_at).each do |attribute, value| %>
<tr>
<td><%= audit[:changed_at].strftime("%m/%d/%Y") %></td>
<td>
<% value.each do |val| %>
<%= val %>
<% end %>
</td>
<td><%= #contract.contract_information.audits.last.user.username %></td>
</tr>
<% end %>
<% end %>

If you have an opportunity to update Espinita in your project, I would recommend you to do it because they changed the format of the hash returned by history_from_audits_for.
In the newer version, you will have something like this in the "History and Restoration" documentation:
model.history_from_audits_for([:name, :settings])
=> [{:changes=>{:name=>"Baz", :settings=>""}, :changed_at=>2015-05-03 15:33:58 -0700},
{:changes=>{:name=>"Arglebargle", :settings=>"IHOP"}, :changed_at=>2015-03-24 15:33:58 -0700},
{:changes=>{:name=>"Walrus"}, :changed_at=>2014-05-13 15:33:58 -0700}]
and your iteration will be as simple as:
<% #contract.contract_information.history_from_audits_for([:contract_title, :assigned_to, :deadline]).each do |audit| %>
<% audit[:changes].each do |attribute, value| %>
<tr>
<%= value %>
<%= audit[:changed_at].strftime("%m/%d/%Y") %>
</tr>
<% end %>
<% end %>
But, if you don't have a chance and you are using Rails > 3.0.0 consider the following approach:
<% #contract.contract_information.history_from_audits_for([:contract_title, :assigned_to, :deadline]).each do |audit| %>
<% audit.except(:changed_at).each do |attribute, value| %>
<tr>
<%= value %>
<%= audit[:changed_at].strftime("%m/%d/%Y") %>
</tr>
<% end %>
<% end %>
using Hash#except.
Retrieve User from Audit
<%= #contract.contract_information.audits.last.user.username %>

Related

Error when trying to link to patient profile

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

Create/New DB record for each generated set of fields

I have got a problem with saving multiple record.
This script wil load a list of instruments that belong to a department through a join table.
This form will make a new record for another join table, the problem is when I'f got 4 instruments it only will save the last instrument.
Image generated list
Can anybody help me out to solve this problem or point me into the right direction ??
<%= form_for(:joindaylisting) do |j| %>
<% #instrumentslist.each do |instrument| %>
<tr class="<%= cycle('odd', 'even') %>">
<td>
<% j.label(:instrument_id, "#{instrument.name}") %>
<%= link_to("#{instrument.name}", {:controller => 'instruments', :action => 'show_instruction', :instrument_id => instrument.id}, :onclick=>"window.open('height=670, width=675');return false;") %>
</td>
<%= j.hidden_field(:instrument_id, :value => instrument.id) %>
<td></td>
<% j.label(:ammountdesinfection, "") %>
<td><%= j.text_field(:ammountdesinfection) %></td>
<% j.label(:ammountinstruments, "") %>
<td><%= j.text_field(:ammountinstruments) %></td>
<% j.label(:ammountrelease, "") %>
<td><%= j.text_field(:ammountrelease) %></td>
<% j.label(:notes, "") %>
<td><%= j.text_area(:notes) %></td>
</tr>
<% j.label(:department_id) %>
<%= j.hidden_field(:department_id, :value => #department.id) %>
<% end %>
<% end %>
Only the last one is saved because the fields have the same name and the last one overrides all other values. See the params you are getting on the receiving controller.
You probably want/need to configure departments to accepts_nested_attributes_for :instruments and a form for the department object with fields_for: instruments. I've highlighted keywords that my help you get the information you want, the Rails Guides is a good place to start.

nil values return error undefined method `car_number' for nil:NilClass even if I check them with .nil?

when I replace the nil values manually with data, I get no errors.
<% #visits.each do |f| %>
<tr>
<td><%=f.owner.car_number unless f.owner.car_number.nil?%></td>
<td><%=f.owner.car_type unless f.owner.car_type.nil?%></td>
<td><%=f.owner.car_year unless f.owner.car_year.nil?%></td>
<td><%=f.owner.first_name unless f.owner.first_name.nil?%> <%=f.owner.last_name unless f.owner.last_name.nil?%></td>
<td><%=f.owner.phone unless f.owner.phone.nil?%></td>
<td style="direction:ltr"><%=f.created_at.strftime("%d/%m/%Y")%></td>
<td>XX NOTES </td>
</tr>
Better you need to add validation to stop entry of nil on owner in visit or the model where the association has defined to owner with visit
here I am consider here visit model has one owner
class Visit < ActiveRecord::Base
has_one :owner
validates :owner, presence: true
end
Or another solution using try
<% #visits.each do |f| %>
<tr>
<% ["car_number", "car_type","car_year", "first_name", "last_name", "phone"].each do |meth| %>
<td><%= f.try(:owner).send(meth) %></td>
<% end %>
<td style="direction:ltr"><%=f.created_at.strftime("%d/%m/%Y")%></td>
<td>XX NOTES </td>
</tr>
<% end %>
I am assuming #visits contains valid list of objects.
Now, lets read the error carefully:
undefined method `car_number' for nil:NilClass
Where are you applying car_number? Hint: to object f.owner. Meaning f.owner is nil , so f.owner.car_number.nil will still throw an error.
Tweak them to:
<%= f.owner.car_number if f.owner %>
Or better:
<% #visits.each do |f| %>
<tr>
<% if f.owner %>
<td><%=f.owner.car_number %></td>
<td><%=f.owner.car_type %></td>
<td><%=f.owner.car_year %></td>
<td><%=f.owner.first_name %> <%=f.owner.last_name %></td>
<td><%=f.owner.phone %></td>
<td style="direction:ltr"><%=f.created_at.strftime("%d/%m/%Y")%></td>
<td>XX NOTES </td>
<% end %>
</tr>
Check the first iteration.
Instead of :
unless f.owner.car_number.nil?
Use..
unless f.owner.nil?
Or you can check first before iterating, like:
<% unless #visits.nil? %>
<% #visits.each do |f| %>
....
<% end %>
<% end %>

Writing a conditional within an each block

I have an array of Twilio Recording SIDs that I'm using to generate links to a users call recording. When I use them in a table and the SID is empty, I'd like to print "No Recording".
<tr>
<% #empty_check.each do |rec| %>
<% if rec.empty? %>
<td><%= "No Recording" %></td>
<% else %>
<td><%=link_to 'listen', "https://api.twilio.com/2010-04-01/Accounts/{#account_sid}/Recordings/" + rec, :target => "_blank"%></td>
<% end %>
<% end %>
</tr>
Even though I know one of the values in that given array is empty, it still prints the else code.
Furthermore, when I do something like this
#empty_check.each {|m| print m.empty?}
falsefalsefalsefalsetruefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalse
I see a true value.
What am I missing in that conditional above that its not recognizing the empty value?
**Update
The #empty_check example was me trying to isolate what I thought was the problem and debugging.
Here is the actual controller code:
#sub_account_client = Twilio::REST::Client.new(#account_sid, #auth_token)
#subaccount = #sub_account_client.account
#calls = #subaccount.calls
#callslist = #calls.list({:page_size => #page_size, :page => #page, :"start_time>" => #start_date, :"start_time<" => #end_date})
#callsids = #callslist.map {|m| m.parent_call_sid}.compact
And the actual view code:
<% #callsids.each do |c| %>
<tr>
<% #call = #calls.get(c) %>
<td><%= Date.parse(#call.date_created).strftime("%m/%d/%y") %></td>
<td><%= Time.parse(#call.start_time).strftime("%I:%M%P") %></td>
<td><%= #call.from %></td>
<td><%= #call.to %></td>
<td><%= ChronicDuration.output(#call.duration.to_i, :format => :short) %></td>
<% #recording = #recordings.get(c) %>
<% #calls.get(#call.sid).recordings.list.each do |rec| %>
<% if rec.sid.empty? %>
<td><%= "No Recording" %></td>
<% else %>
<td><%=link_to 'listen', "https://api.twilio.com/2010-04-01/Accounts/#{#account_sid}/Recordings/" + rec.sid, :target => "_blank"%></td>
<% end %>
<% end %>
</tr>
<% end %>
Are you sure you are accessing the same variable in your print test and the main code block? Try outputting the value of #empty_check within the template just before the test you are interested in (optionally in a comment).
Update to respond to updated question:
<% #calls.get(#call.sid).recordings.list.each do |rec| %>
Isn't that line the issue? If the call has no recordings the whole block will be skipped so it will never write "No recordings.". I'm making guesses about the Twilio API but are you sure that recording objects are returned that have a sid value that returns true for .empty?
Couldn't the above line be simplified to:
<% #calls.get(c).recordings.list.each do |rec| %>
or even:
<% #call.recordings.list.each do |rec| %>
And don't you want to (and try this with the API first) do the if xxx.empty? outside of the each in this case.
<% reclist = #call.recordings.list %>
<% if reclist.empty? %>
<td><%= "No Recording" %></td>
<% else %>
<% reclist.each do |rec| %>
<td><%=link_to 'listen', "https://api.twilio.com/2010-04-01/Accounts/#{#account_sid}/Recordings/" + rec.sid, :target => "_blank"%></td>
<% end %>
<% end %>
Simplified version added after answer accepted. Pulls the tag outside the if (and the each) so that all the links go together in the same table cell if there are multiple recordings for the call.
<% reclist = #call.recordings.list %>
<td>
<% if reclist.empty? %>
No Recording
<% else %>
<% reclist.each do |rec| %>
<%=link_to 'listen', "https://api.twilio.com/2010-04-01/Accounts/#{#account_sid}/Recordings/" + rec.sid, :target => "_blank"%>
<% end %>
<% end %>
</td>

Fulfillment_created_at ror3 shopify api error

How to use arrays and get order date?
I get the date when the order was shipped.( order.line_items_line_item.fulfillment.created_at)
Help plz thx
I'm doing this
controller
#order = ShopifyAPI::Order.find(:all)
views -work
<% #order.each do |order| %>
<span class="highlight"><%= order.customer.email %></span>
<%= order.line_items.each do |line_item| %>
<span class="note"><% line_item.title %></span>
<% end %>
<% end %>
</ul>
<% end %>
views -don't work
<% #order.each do |order| %>
<%= order.line_items.each do |line_item| %>
<span class="note"><% line_item.created_at %></span>
<% end %>
<% end %>
</ul>
<% end %>
views -don't work
<% if #order.line_items %>
<% #order.line_items.each do |line_item| %>
<tr>
<td><%= line_item.created_at %></td>
</tr>
<% end %>
<% end %>
I’m not sure I understand your question, but if you’re looking for when an order was created, you want
#order.created_at
Take a look at the JSON responses in http://api.shopify.com/order.html or do a
puts #order.inspect
to see what kind of data comes back from an Order API call.
Line items don't have a created_at field, they're properties of the order in the same way that adress lines are part of an address.
There's a separate object that deals with order fulfillments. Here's the page on the docs: http://api.shopify.com/fulfillment.html
Using the ruby gem you can just call order.fulfillments to get an array of fulfillments. Then you can loop over those to see when the line items were fulfilled.

Resources