Get ID of an element which is not accessible in the controller - ruby-on-rails

On my project, I am displaying all the rows in the database of a model. However, I am doing this on the index page of another model. And I have a button associated with each row so that when clicked, it'd execute the related action on the associated model. I hope my question is clear enough.
To illustrate the problem, let's say I have two models: Teacher and Student. Every teacher has many students. And in the index page for each teacher, I display all his students as a list of rows. Now, I want to have a button for each row which will change the name of the student when clicked. It doesn't matter where I have the action. It might be in Teacher(or somewhere else). I just wanna find a way for how I will know which student is being clicked. Is it the first or second student whose button got clicked?
How can I do that?
Thank you very much in advance

Something like this?
<% students = Student.all %>
<% students.each do |student| %>
<tr>
<td><%= student.name %></td>
<td><%= link_to 'Change name', '#', onclick: 'alert("ID: "' + "#{student.id})" %></td>
</tr>
<% end %>

Related

How to carry a variable from one page to another

Kinda new to ruby, rails and devise but i'm trying to make a website where users(student) are enrolled in courses, which has its own unique id.
On my loggedin user home page I have a list that displays all courses the student is enrolled in, that pairs the student id to course id on the enrollment table.
<td><%= enrolment.course_id %></td>
<td><%= link_to "Complete Course", home_completeTask_path, class:"btn btn-dark" %></td>
The code I have in my for loop to fill the table of courses the student is enrolled in.
I would like to take enrolment.course_id value from here to home_completeTask where it is used to display the course modules and tasks.
In appllication controller
I have declared a variable:
#Cid
I havn't set it to anything as it would change depending on what the user clicks.
In Home controller
Both pages are in the home directory, and tried to define a method there.
def courseComplete(cid)
link_to "Complete Course", home_completeTask_path, class:"btn btn-dark"
#Cid = (cid)
end
This method didn't work and honestly I can't figure out another way to user that variable.
Any suggestions on this would be great, thanks.
You can pass any parameter as below.
<td><%= enrolment.course_id %></td>
<td><%= link_to "Complete Course", home_completeTask_path(course_id: enrolment.course_id), class:"btn btn-dark" %></td>
and in controllers method you will get same under params[:course_id].

publish the nth attribute from a model

I have a model student with a subject and grade attribute. A student can have many subjects and grades, and what I'd like to do is be able to publish the 2nd or 3rd subject listed for a specific student.
For example, the user searches for a student, then clicks on the student, which brings them to a separate page listing information about that particular student (ie, student id:1). Is there code I can add to the view to list the nth item from the subject and grade attributes?
I looked online here and found similar questions, but those solutions related to the model, not the attributes. For example, one solution recommended using the limit method in the controller and another recommended using the following code:
<% firm.state_of_business.split(',').each_with_index do |state, index| %>
<td> <b>State <%= index + 1 %></b> <%= state %>
This seems to work well, when you don't have a specific model selected. When you select a particular model(ie, student id:1), this doesn't seem to work. At least not for me. Right now my code below is showing the first item. How might I get it to list subject 1 & grade 1, subject 2 & grade 2, subject 3 & grade 3, etc.. See sample code below. Please note, that I tried other solutions on here, but couldn't get them to work, which made me think that my problem might be different than the ones previously presented. Thanks for your help.
View Code
<h2>Students</h2>
<p> Student:
<%= #student.name %>
</p>
<table>
<tr>
<th> Subject </th>
<th> Grade </th>
</tr>
<tr>
<td><%= #student.subject %> </td>
<td><%= #student.grade %> </td>
<tr>
</table>
Controller Show Method
def show
#user = current_user
#student = Student.find(params[:id])
end
Desired Output
Student: Matt Jones
Subject Grade
Math 95
History 90
English 91
Try adding this code:
<%= #student.grade.split(',')[0] %>
The [0] will publish the first item in the array. [1] will publish the 2nd item, etc. That should work.
I guess you can just create another model called Subject and add has_many :subjects in class Student.
In class Subject, you can add this line belongs_to :student.
And then you can do this something like this:
<% #student.subjects.each do |subject| %>
<tr>
<td><%= subject.name %> </td>
<td><%= subject.grade %> </td>
<tr>
<% end %>
Just to make it clear, Subject model contains attribute name and grade in above example.

Ruby on Rails proper way to add a favorite button for front end

So far I have two tables User and Company. Users are able to favorite many companies. I established all the back end code to add favorites (a join table with many to many relationship) I also have a general setup to add favorites.
I need some help with the front end side though.
So far what I have is a search page where users can query a company ticker to get companies. I display it like the following
<% if #results %>
<h4>Search results for <%= #symbol %></h4>
<table>
<tr>
<th>ID</th>
<th>Symbol</th>
<th>Name</th>
</tr>
<% #results.each do |res| %>
<tr>
<td><%= res.id %></td>
<td><%= res.symbol %></td>
<td><%= res.name %></td>
<td><%= link_to "Favorite", create_favorite_path(current_user.id, res.id), method: :post, :remote => true %></td>
</tr>
<% end %>
</table>
<% end %>
Right now I have a "favorite button" implemented with
<td><%= link_to "Favorite", create_favorite_path(current_user.id, res.id), method: :post, :remote => true %></td>
It seems messy and I dont think this is right. I also want to add a few more features
I want to know if the post method was successful or not
Based on the post, I want to be able to change the button text to something like "saved"
later change the link to have a star button icon
I would love suggestions to improve this and do it properly
I prefer using a front-end framework to handle things like this. They allow the components to be much more dynamically interactive.
re: I want to know if the post method was successful or not
in the absence of a front-end framework you can catch failed save in the favorites_controller and add a flash[:error] to the page.
flash[:errors] = #favorite.errors.full_message unless #favorite.save!
re: Based on the post, I want to be able to change the button text to something like "saved"
You can use jQuery to change the button CSS on click of the favorite button.
<% if #results.favorited? %>
# render button with favorited class (with star)
<% else %>
# render button without favorited class (without star)
<% end %>

Ordering a table column alphabetically

I have the following code to display any comments that a user has made in a table on the users show page. The code works fine and a table is diplayed with all of the users comments and the permits they belong to. Currently the table displayed shows the permits in the order they were created by the user. I would like to arrange the table so that the permit column is displayed in alphabettical order instead of when they were created. Im not sure if I need to adjust this code or something in the controller.
<% if #user.comments.exists? then %>
<b>Comments:</b><br />
<table>
<tr>
<th>Permit</th>
<th>Comment</th>
</tr>
<% #user.comments.each do |comment| %>
<tr>
<td><%= link_to comment.permit.name, comment.permit %></td>
<td><%= comment.body %></td>
</tr>
<% end %>
</table>
<% end %>
Use the ActiveRecord order method.
Check the official documentation here: http://guides.rubyonrails.org/active_record_querying.html#ordering
In your case, that would be something like:
<% #user.comments.order('name').each do |comment| %>
> sorted_permits = #user.permits.sort
This gives you a list of permits, ordered naturally (i.e. if they are String values, they are sorted alphabetically, if they are numeric values, they are sorted from lowest to highest). You can do that in your view, or more typically, in your controller.
So, if I have a list of permits such as:
permits = ["Fishing", "Hunting", "Reading", "Driving"]
Then when I can do the following:
> permits.sort
=> ["Driving", "Fishing", "Hunting", "Reading"]
NOTE that .sort returns a copy of the list, in sorted order, while the similar .sort! modifies the original list, reordering it permanently (in memory), but does not change the order/IDs of the permits in the database.
See: http://www.ruby-doc.org/core/classes/Array.html#M000244
Using the :order option directly on the relation definition should do the trick:
class Comment < ActiveRecord::Base
has_many :permits, :order => 'name DESC'
end

Ruby On Rails 3 - Form - Get nested data that are in somehow connected to the form?

I have a form with category, name, size, price and url.
The first 3 have already been filled in and you shouldn't be able to change that data.
Now I want to display the names instead of category_id, name, size_id in a input box. How do I accomplish this?
The nearest I've gotten so far is to create a "select" input with #size.map |s|.... but that is not a good solution. I don't want the user to be able to change these data, so a hidden_field is the best solution I think? But I want to be able to show them the information about the category, name and size.
<%= f.fields_for :price do |pr| %>
<tr>
<td><%= pr.hidden_field :product_id %> <%= Here I want some code showing the name of the product %></td>
<td><%= pr.text_field :price %></td>
<td><%= pr.text_field :url %></td>
<td><%= pr.check_box :_destroy %></td>
</tr>
<% end %>
In my views I have these
#size = ProductSize.all
#products = Product.all
#categories = Category.all
I'm not sure I fully understand how your controller works, but regardless you should be able to get the product, size, and category. You probably have already got them if you were able to set their IDs. In your controller just set the product, size, and category to a variable.
So, in your controller:
#category = YourCategory
#product = YourProduct
#size = YourSize
Then in your form somewhere you can just do something like:
<%=h #category.name %>
<%= Here I want some code showing the name of the product %>
is now
<%= pr.object.name %>
note 'object' does not represent something. just use as typed

Resources