Join two tables data in Rails - ruby-on-rails

Below code is showing parametersname from DataModel table(data base).I have one more table DataModelDevices which has parameter_name column.I want to show parameter_name as well in same row in UI. How to join one more table in rails?
I have tried below code but not working.
<% DataModel.preload(:devices,:revision).where(device: true).where("parametersname NOT LIKE '%.'").where("parametersname LIKE '%{i}%'").order(:id).each do |parameter| %>
<tr onclick="javascript:showRowDeviceTest(this);">
<% DataModelDevices.all.each do |parameterhard| %>
<td style="word-break:break-all;">
<%= parameter.parametersname%>
<%= parameterhard.parameter_name%>
</td>
<% end %>
<% end %>
Actual Working Code
<% DataModel.preload(:devices,:revision).where(device: true).where("parametersname NOT LIKE '%.'").where("parametersname LIKE '%{i}%'").order(:id).each do |parameter| %>
<tr onclick="javascript:showRowDeviceTest(this);">
<td style="word-break:break-all;">
<%= parameter.parametersname%>
</td>
</tr>
<% end %>

you should add association in the models In DataModel:
has_many :data_model_devices
In DataModelDevice:
belongs_to :data_model
You can join with the following code whatever you want:
DataModel.joins(:data_model_devices).
select('data_model_devices.parameter_name, data_models.*').load

Related

Ruby HABTM association loop

i want to achieve a nested loop without duplicates in a have and belongs to many relationship
i have a model 'campaign' and for each campaign i also have campaign data.
i want to display each campaign with its campaign data in a table. (nested)
#campaigns = current_user.campaigns
<% #campaigns.each do |item| %>
<% i = item.campaign_data %>
<% i.each do |cdata| %>
<%= cdata.date %>
<tr>
<td>
<%= item.name %>
</td>
<td>
<%= cdata.date %>
</td>
<td>
</td>
</tr>
<% end %>
<% end %>
my problem is that my campaigns get duplicated.
I want to achieve something like this:
Each campaign is listed in the table with its corresponding campaign_data directly below it, and if no campaign_data is left the next loop begins with the next campaign - is this possible?
best regard
You might be getting duplicated campaigns as you are using <%= item.name %> inside the <% i.each do |cdata| %> loop. So, if one campaign has 4 campaign_datas you will see the campaign name 4 times.
You should use naming conventions properly, if the campaign has many data campaign_data then you should specify so in association i.e. has_many :campaign_datas
Also, the Following code should be in the controller
#campaigns = current_user.campaigns.include(:campaign_datas)
Note:- I used include to avoid n + 1, please read here.
In view
<% for campaign in #campaigns %>
<% next if #campaigns.campaign_datas.blank? %>
<tr>
<td><%= item.name %></td>
</tr>
<% for campaign_data in #campaigns.campaign_datas %>
<tr>
<td><%= campaign_data.date %></td>
</tr>
<% end %>
<% end %>
Note:-
<% next if #campaigns.campaign_datas.blank? %> line is used to skip the campaign if it has no campaign data.

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

rails 5 form_tag with original DB value and after new selection in form, both records must be updated

I have a form_tag with a radio_button_tag and it populates with data from DB. It must simply be directed to a customised update action(update_multiple) where a boolean column is updated for all those 2 records which have been changed in the form.
For e.g. say when initially the form was populated from DB with record 1's radio button selected and now user changed his selection to record 3, then at Submit of form tag the update of both records must occur but the problem is the code at submit, only collects id of record which is now selected in that group.How do I get id of that record also which was unselected so that I can update_all for both of them at one go?
And if Submit cannot handle this action, then is there a way in controller or form to persist the id of the initial selected record before populating the form? As you see, I've tried with collecting an array of ids[] with radio_button_tag.
TIA for your help.
Here's the form code:
<%= form_tag update_multiple_user_cv_attachments_path, method: :put, action: :update_multiple do %>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th> Select a CV </th>
<th> Resume Name </th>
</tr>
</thead>
<tbody>
<% #cv_attachments.each do |cv_attachment| %>
<%= hidden_field_tag cv_attachment.main, :value => params[:main] %>
<tr>
<td><%= radio_button_tag "cv_attachment_ids[]", cv_attachment.id, cv_attachment.main %> </td>
<td><%= cv_attachment.attachment.file.basename %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= submit_tag "Select Main", :class =>'button' %>
<% end %>
Here's the controller update_multiple code.
def update_multiple
CvAttachment.update_all(["updated_at=?", Time.now], :id => params[:cv_attachment_ids])
end
I can think of 2 ways to achieve your objective.
update the boolean for all the attachments which belong to the user to false and then update the one which has been selected to true
include a hidden field in the form and set it to the id that is already true. Then in the controller action, update the one that is selected to true and the one in the hidden field to false. This is probably a better option and you'll probably want to wrap the d/b updates in a transaction.
<tbody>
<% #cv_attachments.each do |cv_attachment| %>
<% if cv_attachment.main %>
<%= hidden_field_tag "ex_main_cv", cv_attachment.id %>
<% end %>
<tr>
<td><%= radio_button_tag "main_cv", cv_attachment.id, cv_attachment.main %> </td>
<td><%= cv_attachment.attachment.file.basename %></td>
</tr>
<% end %>
</tbody>
controller
def update_main_attachment // probably a better name for this method
if params["ex_main_cv"] != params["main_cv"]
Attachment.transaction do
deselected_attachment = Attachment.find(params["ex_main_cv"]
deselected_attachment.update_attribute(:main, false)
selected_attachment = Attachment.find(params["main_cv"]
selected_attachment.update_attribute(:main, true)
end
end
end
Many thanks #margo. Here' how I resolved it partly your way of using hidden_field. But for now keeping this thread open as I'm making 2 DB updates for toggle of same column.
<tbody>
<% #cv_attachments.each do |cv_attachment| %>
<% if cv_attachment.main %>
<%= hidden_field_tag "ex_main", cv_attachment.id %>
<% end %>
<tr>
<td><%= radio_button_tag "new_main", cv_attachment.id, cv_attachment.main, :id => "#{cv_attachment.id}"%> </td>
<td><%= cv_attachment.attachment.file.basename %></td>
</tr>
<% end %>
</tbody>
and in controller:
def update_main
if request.put?
if params["ex_main"] != params["new_main"]
CvAttachment.find(params[:ex_main]).toggle!(:main)
CvAttachment.find(params[:new_main]).toggle!(:main)
end
end

Ordering by date in Ruby on Rails

I am iterating over a set of objects in Ruby on Rails like so :
<% #subject.Association.each do |horse| %>
<tr>
<td>
<%= horse['Name'].to_s %>
<%= horse['Size'] %>
</td>
</tr>
<% end %>
The horse object has a date field, called dateRode.
I would like to order by this field.
I am not a ruby developer, but I tried a number of ways to do this resulting in only syntax errors e.g
<% subject.association.each do |horse|-> { order by "dateRode" DESC } %>
How can I do this in my code without editing ActiveRecords etc?
You can order collection with order method like this:
<% #subject.Association.order(dateRode: :desc).each do |horse| %>
<tr>
<td>
<%= horse['Name'].to_s %>
<%= horse['Size'] %>
</td>
</tr>
<% end %>
Try to replace this:
<% #subject.Association.each do |horse| %>
with
<% #subject.Association.order(dateRode: :desc).each do |horse| %>
Hoping that it would help you.
<% subject.association.each do |horse|-> { order by "dateRode" DESC } %>
The above is a mix of erb and sql which isnt going to work.
The best way to do it is to create a scope in the model which is called by the controller.
model
def self.order_by_date_rode
Model.includes(:association).order("associations.dateRode desc")
end
where Model is the name of your model and association is the name of the association you want to order by.
controller method
def some_method
#subject = Model.order_by_date_rode
end
A less recommended way is to do the sorting in the view
<% #subject.Association.order(dateRode: :desc).each do |horse| %>
the another way is that you can set a default scope for ordering of the association model like below
class Association < ActiveRecord::Base
default_scope { order('dateRode DESC') }
end
so when you do <% #subject.Association it will automatically sort

How to Handle 2 tables with one form_tag? Rails 3

Beneficiaries
id (PK)
name
age
income
Beneficiary_loans
id (PK)
beneficiary_id (FK)
amount
rate
period
What I'm doing is, selecting a list of beneficiary from [Beneficiaries] table and displaying as follows
<%= form_tag({:action => 'update_survey_list_status', :status=>4}) do %>
<table width="100%">
<tr>
<th>Beneficiary Details</th>
<th>Amount</th>
<th>Rate</th>
<th>Period</th><th>
<input type='checkbox' name='checkall' onclick='checkedAll();'>
</th>
</tr>
<% #publishedlist.each do |b| %>
<tr>
<td><%= b.firstname %></td>
<%= fields_for :beneficiaryloan do |bloan| %>
<td> <%= bloan.text_field :amount%></td>
<td> <%= bloan.text_field :rate%></td>
<td> <%= bloan.text_field :period%></td>
<% end %>
<td><%= check_box_tag "benificiary_ids[]",b.id, :name => "benificiary_ids[]"%> </td>
</tr>
<% end %>
</table> <%= submit_tag "Approve", :class=>'form_buttons' %>
<% end %>
In controller,
#beneficiaries=Beneficiary.find(:all, :conditions => ["id IN (?)", params[:benificiary_ids]])
#beneficiaries.each do |b|
#beneficiaryloan = Beneficiaryloan.new(params[:beneficiaryloan])
#beneficiaryloan.beneficiary_id=b.id
#beneficiaryloan.hfi_id=session[:id].to_s
#beneficiaryloan.status_id=params[:status]
#beneficiaryloan.save
end
What I'm not getting is
params[:beneficiaryloan]
Values are coming as NULL
Am I missing something here in this form?
Check the following,
With the help of any browser tool(eg:firebug), make sure that the form has been rendered properly. Sometimes due to some misplaced tags(generally happens with table structure) the form does not renders properly.
Try to remove the table structure and see if the form works.
Make sure your association is fine, i guess it should be Beneficiary has many Beneficiaryloan
If none of the above helps, please post the request parameters over here.

Resources