Storing selected IDs, fetching to display in a custom routed view - ruby-on-rails

I'm still new to Rails, and can't seem to wrap my head around this.
I have table showing of several Products with several attributes in form columns. In my index view I'm showing a shortened table, with just some of the columns. In my products#show I'm telling the full story, but obviously only for the selected Product. What I want to do, is letting users select a number of Products in products#index, and then store the selected IDs in a hash, sending them to another view, which I want the IDs to be presented in a full scale table, telling the whole story, of several products at once. Basically this is for comparing Products.
I'm not sure how to tackle this. As I'm already using DataTables, using javascript would make sense, but I'm unsure on how. And ideas? I've tried several ideas, but none of them got me anywhere.
products#index
<table id="products"cellpadding="0" cellspacing="0" border="0" class="table.responsive">
<thead>
<tr>
<th></th>
<th>Product Name</th>
<th>TG</th>
<th>TD</th>
<th>DK</th>
<th>DF</th>
<th>T260</th>
<th>T288</th>
<th>CTI</th>
<th>Strength</th>
<th>Rigidity</th>
<th>Standards</th>
<th>Manufactorer</th>
</tr>
</thead>
<tbody>
<% #products.each do |product| %>
<tr>
<td><%= check_box_tag "product_ids[]", product.id %></td>
<td><%= link_to product.name, product %></td>
<td><%= product.TG %></td>
<td><%= product.TD %></td>
<td><%= product.DK %></td>
<td><%= product.DF %></td>
<td><%= product.T260 %></td>
<td><%= product.T288 %></td>
<td><%= product.CTI %></td>
<td><%= product.ElectricStrength %></td>
<td><%= product.rigidity %></td>
<td><% product.standards.each do |standard| %>
<%= link_to standard.name, standard %>,
<% end %> </td>
<td><%= product.producer %></td>
<% end %>
</tr>
</tbody>
</table>
If anyone could spare some time to point me in the right direction, that would be wonderful!

This shouldn't be too tough to tackle, I'll walk you through the basic steps that I would take.
My basic approach would be to take a form of said checkboxes and submit it to an action designed to handle them in the way described, like so:
Create a new route to use for all of this. Take a look at 2.10.2 Adding Collection Routes in the docs (assuming you are using resources). Maybe call it something like "compare".
Use a form not backed by a model to hold your checkboxes and labels (1 of each for each product) - it should post to your new route.
In your controller, add the action for your route. This action should fetch the ids passed in by the form from the params and load the relevant products (remember that find can take an array of ids, so it should be pretty easy).
Finally, add a view for your new action, with the relevant logic to present your comparison.
You can easily come in an backfill this with javascript, but it is not required. Honestly, it would be more useful for adding a little extra panache, like disabling the button and showing a spinner, or something, than a full-on javascript submission, which doesn't really buy you anything in this particular case.

Related

Sorting columns in HTML table using Rails or Bootstrap?

I'm looking for the best way to implement click (arrow icons) sort per column in an HTML table (not the database table). Is this best done with the boostrap-sortable plugin or best to try and implement an action in Rails to sort (controller method). It currently loads A-Z by name, as implemented by the query.
I have tried referring to: https://mdbootstrap.com/docs/jquery/tables/sort/ but received console errors that DataTables(); could not be found.
#users = User.all
<thead>
<th></th>
<th>Name</th>
<th>State</th>
<th>Phone</th>
</thead>
<tbody>
<% #users.each do |user| %>
<tr>
<td></td>
<td><%= user.full_name %></td>
<td><%= user.state %></td>
<td><%= number_to_phone(user.phone_number, area_code: true) %></td>
</tr>
<% end %>
</tbody>
</table>
Javascript console: "DataTable();" cannot be found.
IMHO I think is better to implement the sort option in the backend, because your list could have 10000 records and you are showing for example 10 per page. If you are delegating the process in the client-side I think this is not a good strategy.
Maybe you can implement a scope in order to resolve the problem. The index action of the controller must have params in the query string to apply for the order.
example:
myurl?order=asc&by=name
Then in the index action you

Rails create table row on button click

So this may be slightly confusing but i hope to make it work fine.
So at the moment i have this a table, Which looks like this,
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>EventName</th>
<th>Description</th>
<th>Initial Provider</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<% #newevents.each do |ne| %>
<tr>
<td><%= ne.id %></td>
<td><%= ne.product_name %></td>
<td><%= ne.description %></td>
<td><%= ne.merchant_name %></td>
<td><%= link_to "Edit Event", edit_event_path(ne.id), class: "btn btn-info" %></td>
</tr>
<% end %>
</tbody>
</table>
At the moment i have this loading in from DBTable1
Now, I'm wanting it so that when you click on the edit button. It will take you to a page where it can load in information from DBTable1 but save the information into DBTable2
At the moment. DBTable2 has a DBTable1_id field inside. But i haven't worked out fully how to use it. DBTable1 does have has_one DBTable2 inside
How do i go about making this so that when you edit your actually creating a new row in DBTable2 from the view?
Seems like you need to simply adjust the controller action (or create a new action) that acts just like "update", but creates a new one instead.
Actually, you can probably do this by changing edit_event_path(ne.id) to something else like, create_event_path(ne.id) or new_event_path(ne.id).
Although, don't know enough about your app (including what it's routes are) to be sure.

Remove duplicates in view Rails

A minor, perhaps simple, question here. Let's say my DB returns duplicates. For example, I have multiple rooms that contain different start and end times.
My current view looks like:
<table>
<thead>
<tr>
<th>Location</th>
<th>Status</th>
<th colspan="1"></th>
</tr>
</thead>
<tbody>
<% #courses.each do |course| %>
<% if course.lec_exam.eql?("LEC")%>
<tr>
<td><%= course.location %></td>
<td><%= course.status %></td>
<td><%= link_to 'Edit Status', edit_course_path(course) %></td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
I'd like to clean this up a bit and remove the duplicates. Since each course has a location and start and end times, the same location will get displayed multiple times. What is the best approach to prevent this and display the unique locations, and then ensure that the status is correctly marked (i.e. closed means the current time is between the start and end time for each course that uses that location)? I have a few ideas but I'm not certain where to start. I can provide more information as needed.
Thanks!
Probably you can use Distinct SQL operator
http://guides.rubyonrails.org/active_record_querying.html
But I didn't get idea of your seconds part of question

Correct way of conditional rendering within a partial in Rails?

I have created a partial for a LineItem that, in my case, emits a <tr> with a couple of <td>s. This works just fine and dandy.
What I'd want to do then, is use the same partial in different places. The original view has plenty of room, so displaying every cell is ok. But another (a sidebar), has much less space, and I'd only want to display two of the 5 cells.
So the question, then, is what is the correct way of implementing this? I'd like for the "full" version to be the default unless otherwise specified, and only use the limited version if a parameter is passed.
Currently I'd probably use the feature of passing locals to a partial and check if a parameter limited is defined, and if so, skip the last N cells. Am I on a right track, and if so, what kind of a variable should I use (can I use symbols for this)?
Current _line_item.html.erb (that I'm somewhat unhappy with)
<tr>
<td><%= line_item.quantity %>×</td>
<td><%= line_item.product.title %></td>
<td class="item_price"><%= number_to_currency(line_item.total_price, unit: '€') %></td>
<% unless defined? limited %>
<td class="remove_item"><%= button_to 'Remove', line_item, method: :delete %></td>
<% end %>
</tr>
Edit: Added current version.
Yes, you are on the right track. You can do something like
<%= render 'partial_name', limited: true %>
and then in the partial:
<% limited ||= false %> # More explicit as to what default value is
<tr>
<td><%= line_item.quantity %>×</td>
<td><%= line_item.product.title %></td>
<td class="item_price"><%= number_to_currency(line_item.total_price, unit: '€') %></td>
<% unless limited %>
<td class="remove_item"><%= button_to 'Remove', line_item, method: :delete %></td>
<% end %>
</tr>

How can I display data for the current view from a different table

I have two tables:
Chords - |id|chord|name|rating|artist_id|
Artists - |id|artist|
An Artist has many Chords, and thus a Chord belongs to an Artist.
And in the index page for "chords" I want to display chord, name, and rating from Chords table and the artist from the artists table
This is the code for the Chord's index.html.erb:
<table border="1">
<% #chords.each do |chord| %>
<tr>
<td><%= chord.artist.artist %></td>
<td><%= link_to chord.name, chord %></td>
<td><%= chord.rating %></td>
<td><%= chord.created_at %></td>
</tr>
<% end %>
</table>
The error message is:
undefined method `artist' for nil:NilClass
Actually, at first it worked, but when I started to create the "new.html.erb" page and the create and new actions, it stopped working, that's why this is so confusing to me!
Since chort.artist can be null, you should change chord.artist.artist to chord.artist.try(:artist) which is shorthand for
if chord.artist.nil?
nil
else
chord.artist.artist
end
You could use
<td><%= chord.artist.artist unless chord.artist.artist.nil? %></td>
In the view is no the right place to do it but what you need to do is find the artist with the ID given in the CHORDS like this
#currentArtist = Artist.find(:all, :conditions => {:protectora => Chord.artist_id})
Then when you find it by the ID given in the CHORD and save it in to a variable, you can access it like any other variable so:
#currentArtist.artist
Hope it helps.

Resources