Rails search table clickable link - ruby-on-rails

I have a keyword search page for which the results are presented in a table. One of the fields in this table is a url which I want to display as a clickable link when the field has one in it but I can't get this working, when the link is clicked it instead queries the search again. I think the problem is due to the def within the searches controller dealing with the keywordsearch view. Can anybody help?
Below is the keywordsearch view which contains the results table:
<!-- Index of all Courses -->
<% provide(:title, "Courses Page") %>
<!--Breadcrumbs -->
<br>
<%= link_to "Back", :back %><br><br>
<!--Page Contents -->
<div class ="row">
<h1>Degrees Offered</h1>
<%= image_tag "line.png" , :alt => "line break"%>
</div>
<div class ="row">
<!-- Form for Keyword Search, to query database for University courses. It is hidden so as to not appear as a search on the page -->
<div class = "hidden">
<%= form_tag(keywordsearch_path, :method => "get", id: "search-data") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search course" %>
<%= submit_tag "Search" %>
<% end %>
</div>
<% if #search_degree != nil %>
<% end %>
<% if #search_degree != nil %>
<table border="1" class="table">
<thead>
<tr>
<th>University Name</th>
<th>Course Name</th>
<th>Duration</th>
<th>Qualification</th>
<th>Entry Requirements</th>
<th>Course Page</th>
</tr>
</thead>
<tbody>
<% #search_degree.each do |degree| %>
<tr>
<td><%= degree.uname %></td>
<td><%= degree.cname %></td>
<td><%= degree.duration %></td>
<td><%= degree.qualification %></td>
<td><%= degree.entry %></td>
<td> <a href=<% degree.url %>>View course page on University Website</a></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</div>
Below is portion of the search controller in which keyword search is defined:
def keywordsearch
#search = Degree.all.select(:uname, :cname, :ucas, :duration, :qualification, :entry).distinct.order(id: :ASC)
if params[:search]
#search_degree = Degree.search(params[:search]).order('uname ASC')
end
end
The link from all of this is clickable but rather than taking me to the correct url it redoes the search.

try this instead of hardcoding the <a> tag:
<%= link_to 'View course page on University Website', degree.url %>
Can you also post a sample of url? Be sure to include the protocol (e.g, http://...)

Related

How to select multiple items to delete (via checkbox) in Rails 6

I created a column of checkboxes where in users can select multiple items to delete on a table. Something like this but only a button "Bulk Delete":
Here's my code:
<%= render "shared/nav_dashboard" %>
<%= render "shared/header_dashboard" %>
<section>
<div class="container-fluid">
<!-- Page Header-->
<header>
<h1 class="h3 display">Pages</h1>
</header>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>List of Pages</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th><%= link_to "Bulk Delete", page_path(page), method: :delete, data: { confirm: "Are you sure?" }%></th>
<th>Id</th>
<th>Title</th>
<th>Summary</th>
<th>Date Created</th>
<th colspan="3">Action</th>
</tr>
</thead>
<tbody>
<% #pages.each do |page| %>
<tr>
<td><input type="checkbox" value="false"> </td>
<td scope="row"><%= page.id %></td>
<td><%= page.title %></td>
<td><%= page.body.truncate(60) %></td>
<td> <%= page.created_at.strftime("%B %d, %Y") %> </td>
<td><%= link_to "Show", page_path(page)%></td>
<td><%= link_to "Edit", edit_page_path(page)%></td>
<td><%= link_to "Delete", page_path(page), method: :delete, data: { confirm: "Are you sure?" }%></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
<%= render "shared/footer_dashboard" %>
I am wondering why it did not work?
How can I do this functionality step by step?
You could to use a form. It'll look something like this (I'm using simpleform, but this will work for every your preferred form-tag helper):
In routes.rb:
resources :pages do
collection do
delete :bulk_destroy
end
end
In your view:
<%= simple_form_for :pages, url: "/pages/bulk_destroy", method: :delete do |f| %>
<ul>
<% #pages.each do |page| %>
<li> <%= page.name %> <input type="checkbox" name="collection_ids[]" value="<%= page.id %>" /> </li>
<% end %>
</ul>
<%= f.submit %>
<% end %>
In your controller:
class PagesController < ApplicationController
def bulk_destroy
Page.where(id: params[:collection_ids]).destroy_all
end
end
Heavy-lifting taken care for you: https://github.com/joshmn/active_action or check out the bare-minimum proof of concept at https://github.com/joshmn/bulk_actions_poc
if you don't prefer to write other separate method then you can try like below, you just need to be sure that when multiple ids are selected it should send as params[:ids] rather then params[:id]
def destroy
ids = params[:ids].present? ? params[:ids] : [parmas[:id]]
Pages.where(id: ids).destroy
end
you might need to change syntax based on you jquery version
$('#bulk_delete').on('click', function(e){
var selectedIds = [];
$("input[type='checkbox']:checked").each(function(e){
ids.push($(this).data('id'))
})
$.ajax({url: 'your action url',type: 'DELETE', data: {ids: selectedIds}})
})

Rails 5 ActiveRecord Update Serialized Array in Form

I have a field that is a serialized array. It's loaded into my model and accessed in a form:
class Site < ApplicationRecord
serialize :steps, Array
end
<table class="listing" summary="Site list">
<tr class="header">
<th>Name</th>
<th>Step 1</th>
<th>Step 2</th>
<th>Step 3</th>
<th>Actions</th>
</tr>
<% #sites.each do |site| %>
<tr>
<td><%= site.name %></td>
<% site.steps.each do |step| %>
<td><%= step %></td>
<% end %>
<td class="actions">
<%= link_to("Show", site_path(site), :class => 'action show') %>
<%= link_to("Edit", edit_site_path(site), :class => 'action edit') %>
<%= link_to("Delete", delete_site_path(site), :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
I'm trying to update my edit form so that I can edit each "step" in the array.
<%= form_for(#site) do |f| %>
<table summary="Site form fields">
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<% a=1 %>
<% #site.steps.each do |step| %>
<tr>
<th>Step <%= a %>
<td><%= text_field :site, :steps, :value => step %></td>
<% a += 1 %>
</tr>
<% end %>
</table>
<div class="form-buttons">
<%= f.submit("Update Site") %>
</div>
<% end %>
The edit form displays the steps field correctly as each individual string in the array. However, when I attempt to submit the form I get the following error:
Attribute was supposed to be a Array, but was a String.
So steps is being submitted as the last entry in the array. How can I display the form correctly and also present the updated array back to the controller for processing?
Your text_field would need to multiple set to true. I believe in your case, something like this should work.
<%= f.text_field(:steps, { multiple: true, value: #site.steps[step] }) %>

Rails REST doesn't show/load the right page - Ruby on Rails

Basically I created a controller, model and view for subjects. Basically I have 6 actions inside my controller and set up a REST inside my routes file to route the right file.
When I entered, http://localhost:3000/subjects/index it shows me the view for show.html.erb instead of the index.html.erb
Here's what my subject controller looks like:
class SubjectsController < ApplicationController
def index
#subjects = Subject.sorted
end
And here's the content of my index.html.erb file.
<% #page_title = "All Subjects" %>
<div class="subjects index">
<h2>Subjects</h2>
<%= link_to("Add New Subject", new_subject_path, :class => "action_new") %>
<table class="listing" summary="Subject list" border="1">
<tr class="header">
<th>#</th>
<th>Subject</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<% #subjects.each do |subject| %>
<tr>
<td><%= subject.position %> </td>
<td><%= subject.name %> </td>
<td class="center"><%= status_tag(subject.visible) %></td>
<td class="center"><%= subject.pages.size %> </td>
<td class="actions">
<%= link_to("View Pages", pages_path(:subject_id => subject.id), :class => 'action show') %>
<%= link_to("Show", subject_path(subject), :class => 'action show') %>
<%= link_to("Edit", edit_subject_path(subject), :class => 'action edit') %>
<%= link_to("Delete", delete_subject_path(subject), :class => 'action delete') %>
<td>
</tr>
<% end %>
<table>
</div>
Also here's what I set up on my routes:
resources :subjects do
member do
get :delete
end
end
Any idea what am I missing?
The answer is simple: in order you access the index page, you need to hit the following URL:
http://localhost:3000/subjects
Obviously, it will be with GET
The reason why you got the error is: since, anything of the format subjects/:id will take you to the show action within SubjectsController, so Rails interprets subjects/index as you are trying to access the page subjects/:id with index as id of the subject. Here's nothing wrong with Rails, since in RESTful web services, you access the index page by ONLY using the plural name of the resource, like in your case http://localhost:3000/subjects

Dynamic checkboxes to send array to controller only sending first choice

I have a table of data created like so:
<% #products.each do |product| %>
<tr>
<td><%= form_tag push_to_products_path(product), :id =>
'submit_products' do %>
<%= check_box_tag('send[]', product.sellersku) %>
<% end %>
</td>
<td><%= product.title %></td>
<td><%= product.asin %></td>
<% end %>
</tr>
I created the nested form_tag because I have a button outside of the form that uses the checkbox data to send to my Product controller. This is the button code:
<div class="row pad_bottom col-md-4 col-md-offset-1 text-center">
<button type="submit" form="submit_products" class="btn btn-primary">
<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Push
Selected Products
</button>
</div>
The checkboxes are correctly created in the view, but when I test only the first box has the sellersku value.. all the other checkboxes don't pass anything. They should also be passing the sellersku.
Pretty sure its my loop, just not sure what I did wrong??
Declare your form outside of the loop. Right now, you're looping through your #products and creating a form for each one.
<%= form_tag push_to_products_path, :id => 'submit_products' do %>
<% #products.each do |product| %>
<tr>
<td><%= check_box_tag('send[]', product.sellersku) %></td>
<td><%= product.title %></td>
<td><%= product.asin %></td>
</tr>
<% end %>
<%= submit_tag("Push Selected Products") %>
<% end %>
<%= form_tag products_push_to_path, :id => 'submit_products' do %>
<% #products.each do |product| %>
<tr>
<td><%= check_box_tag('send[]', product.sellersku) %>
</td>
<td><%= product.title %></td>
<td><%= product.asin %></td>
</tr>
<% end %>
<%= submit_tag "Push Selected Products" %> #replace this with glyphicon part
<% end %>
routes.rb #assuming your action name is push_to with resources products
resources :products do
collection do
post 'push_to'
end
end

Accept Nested Attributes not working as expected

So I have an entity form that accepts nested attributes for another entity. This renders perfectly fine. However, the nested form is not functioning as I would like it to. See below:
<table class="datagrid">
<thead class="datagrid">
<th width="300" align="left"> Item</th>
<% unless current_user.is_partner? %>
<th width="100"> Location</th>
<% end %>
<th> Amount Requested</th>
<th> Amount Checked Out</th>
</thead>
<% session[:clicked_request].items.each do |item| %>
<tr class="<%= cycle('dg_list_line_odd', 'dg_list_line_even') %>">
<td> <%= link_to "#{item.name}", item_path(item) %></td>
<% unless current_user.is_partner? %>
<td> <%= item.location.name %></td>
<% end %>
<td> <%= item.requested %></td>
<td><%= f.text_field :amount, :value => item.requested, :size => 1 %></td>
</tr>
<% end %>
</table>
<p> </p>
As you can see there is an "each" loop here, that allows for the display, and hopefully the creation, of multiple items. However, when I press the submit button, regardless of how many items are present, only one of them is created.
Your suggestions are much appreciated.
That's not how you render forms with accepts_nested_attributes
Assuming f is a form builder bound to the parent object, you need to do something like
<%= f.fields_for :items do |item_form| %>
<%= item_form.text_field :amount
<% end %>
The block will be executed once for each item in the collection. In addition, item_form is setup with the right prefix for the controller side to work properly.

Resources