I'm new at Ruby on Rails (I started studying this week by myself) and I'm facing some issues that I cannot solve.
I have created a project called 'projeto_ajuda' and i'm using mysql database. I access the aplication on http://localhost:3000/menu/index. It shows me a table with 5 columns, and the last one, is for a button.
What I want is: when the button is clicked, it calls a method from the controller that 'refresh' the table with a new select (i add a new condition in where statement).
Ps¹: the view show to filled rows in the table, but when I click on the button, nothing changes on the view, but the URL does: http://localhost:3000/menu/index.%23%3CMenu::ActiveRecord_Relation:0x007f5ce5891608%3E?id=6
Ps²: If I refresh_table(6) instead of refresh_table(nil) on the index method, it works just fine, selecting what I want from the database.
And if I look at the database, there is a record with the id 6.
menu_controller.rb:
class MenuController < ApplicationController
helper :all
def index
refresh_table(nil)
end
def abrir
refresh_table(params[:id])
end
private
def refresh_table(id)
if(id.nil?)
#menus = Menu.where("codigopai IS NULL")
else
#teste = Menu.find(id)
#menus = Menu.where("codigopai = '" + #teste.codigopai.to_s + #teste.codigo.to_s + "'")
end
end
end
index.html.erb:
<h1> List all </h1>
<table>
<tr>
<th>Codigo</th>
<th>CodigoPai</th>
<th>Descrição</th>
<th>Conteúdo</th>
<th></th>
</tr>
<% #menus.each do |m| %>
<tr>
<td><%= m.codigo %></td>
<td><%= m.codigopai %></td>
<td><%= m.descricao %></td>
<td><%= m.conteudo %></td>
<td><%= button_to 'Abrir', menu_index_path(#menus, :id => m.id), method: :post %></td>
</tr>
<% end %>
</table>
routes.rb:
Rails.application.routes.draw do
resources :menus
post 'menu/index'
get 'menu/index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Try this
menu_controller.rb
class MenuController < ApplicationController
helper :all
def index
refresh_table(params[:id])
end
private
def refresh_table(id)
if id
#teste = Menu.find(id)
#menus = Menu.where(codigopai: "#{#teste.codigopai}#{#teste.codigo}")
else
#menus = Menu.where(codigopai: nil)
end
end
end
index.html.erb
<h1> List all </h1>
<table>
<tr>
<th>Codigo</th>
<th>CodigoPai</th>
<th>Descrição</th>
<th>Conteúdo</th>
<th></th>
</tr>
<% #menus.each do |m| %>
<tr>
<td><%= m.codigo %></td>
<td><%= m.codigopai %></td>
<td><%= m.descricao %></td>
<td><%= m.conteudo %></td>
<td><%= button_to 'Abrir', menu_index_path(id: m.id), method: :post %></td>
</tr>
<% end %>
</table>
I think you can read Query with Active Record and routing
Related
On my index page, I succeeded in listing all of my 'games' in a table, unfortunately, another list, that isn't part of my index.html.erb file code also appears, above my table.
I don't understand how this is possible as my html file doesn't contain any element at the place the list appears on the browser... If someone has an idea that would be very nice !
Here's a photo of what appears on the browser :
browser problem snapshot
Here's my index.html.erb code :
<div class="container full-height">
<div class="abs-center">
<table class="table">
<thead>
<tr>
<td colspan="6">GAMES</td>
</tr>
</thead>
<tbody>
<%= #games.reverse.each do |g| %>
<tr>
<td><%= g.id %></td>
<td><%= g.score_1 %></td>
<td><%= g.score_2 %></td>
<td><%= g.created_at %></td>
<td><%= link_to 'see game', game_path(g) %></td>
<td><%= link_to 'modify', edit_game_path(g) %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
My game controller index method :
def index
#games = Game.all
end
Thanks a lot !
Remove = before <%= #games.reverse.each do |g| %>. = renders a result of an expression, in your case, it is each method, that returns the collection.
Must look as this <% #games.reverse.each do |g| %>
Hello i am new on ruby on rails.I am trying to build a page that have a date field, and after choosing a specific date, i want to generate a table that shows reports of this date select.
controllers/reports_controller.rb
class ReportsController < ApplicationController
def index
end
def test
#chosen_date = params[:report_date]
#incoming_messages = Message.where("inbound = 't' and created_at like '" + #chosen_date + "%'").count
#total_chats = Message.where("created_at like '" + #chosen_date + "%'").distinct.count(:phone_number)
#enrollment_by_andi = Enrollment.where("created_at like '" + #chosen_date + "%' and created_by = 'ANDI'").count
#enrollment_by_agent = Enrollment.where("created_at like '" + #chosen_date + "%' and created_by <> 'ANDI'").count
#sent_by_andi = Message.where("created_by = 'ANDI' and created_at like '" + #chosen_date + "%'").count
#sent_by_agents = Message.where("inbound = 'f' and created_by <> 'ANDI' and created_at like '" + #chosen_date + "%'").count
#unread_messages = Message.where("created_at like '" + #chosen_date + "%' and is_read = 'f'").distinct.count(:phone_number)
end
end
views/reports/index.html.erb
<h1>Reports</h1>
<%= form_tag(reports_test_path,:method => "post") do %>
<%= label_tag(:report_date,"Choose a Date") %>
<%= date_field_tag(:report_date)%>
<%= button_tag "Submit"%>
<% end %>
table i want to generate:
<table>
<th>
<td>Incoming Messages</td>
<td>Total Chats</td>
<td>Enrollment By Andi</td>
<td>Enrollment By Agent</td>
<td>Sent By Andi</td>
<td>Sent By Agents</td>
<td>Unread Messages</td>
</th>
<tr>
<td><%= #incoming_messages %></td>
<td><%= #total_chats %></td>
<td><%= #enrollment_by_andi %></td>
<td><%= #enrollment_by_agent %></td>
<td><%= #sent_by_andi %></td>
<td><%= #sent_by_agents %></td>
<td><%= #unread_messages %></td>
</tr>
</table>
Below is the image of the page:
Anyone can help me to find a method to generate a table under the date field when i press the button ?
You can use AJAX which goes really well with rails and is really decent. For this follow the following steps -
First create a partial _report_table.html.erb. You have a little problem in the table. So paste the below table html in the partial -
<table>
<tr>
<th>Incoming Messages</th>
<th>Total Chats</th>
<th>Enrollment By Andi</th>
<th>Enrollment By Agent</th>
<th>Sent By Andi</th>
<th>Sent By Agents</th>
<th>Unread Messages</th>
</tr>
<tr>
<td><%= #incoming_messages %></td>
<td><%= #total_chats %></td>
<td><%= #enrollment_by_andi %></td>
<td><%= #enrollment_by_agent %></td>
<td><%= #sent_by_andi %></td>
<td><%= #sent_by_agents %></td>
<td><%= #unread_messages %></td>
</tr>
</table>
create a js file as test.js.erb as your post method name is test which puts the table html in a div in index.html.erb
$('#report_table').html("<%= escape_javascript(render partial: 'report_table') %>");
add a div with report_table id in index.html.erb after the form
<div id="report_table"></div>
Add remote true in the form
form_tag(reports_test_path,:method => "post",:remote=>true)
add return in the test method which will render the required js file
respond_to do |format|
format.js
end
That should do it. Please let me know if you have any connfusion
You can submit the form by ajax by setting remote: true on the form tag:
<%= form_tag(reports_test_path,:method => "post", remote: true) do %>
<%= label_tag(:report_date,"Choose a Date") %>
<%= date_field_tag(:report_date)%>
<%= button_tag "Submit"%>
<% end %>
You then create a corresponding `app/views/reports/test.js.erb view file that generates the actual JavaScript code that will be sent and executed on the client side.
You can put the table in a partial, say app/views/reports/_table.html.erb and render it in the javascript:
var tableContainer = document.getElementById(...);
tableContainer.insertAdjacentHTML('beforeend', '<%= j render partial: "/reports/table" %>');
If you're not too familiar working with ajax and javascript, check out the Ruby on Rails guides
You can do this with server-side rendering
Add a template file with the following content:
views/reports/test.html.erb
<h1>Reports</h1>
<%# The date field from the index.html %>
<%= form_tag(reports_test_path,:method => "post") do %>
<%= label_tag(:report_date,"Choose a Date") %>
<%= date_field_tag(:report_date)%>
<%= button_tag "Submit"%>
<% end %>
<%# the new content %>
<table>
<th>
<td>Incoming Messages</td>
<td>Total Chats</td>
<td>Enrollment By Andi</td>
<td>Enrollment By Agent</td>
<td>Sent By Andi</td>
<td>Sent By Agents</td>
<td>Unread Messages</td>
</th>
<tr>
<td><%= #incoming_messages %></td>
<td><%= #total_chats %></td>
<td><%= #enrollment_by_andi %></td>
<td><%= #enrollment_by_agent %></td>
<td><%= #sent_by_andi %></td>
<td><%= #sent_by_agents %></td>
<td><%= #unread_messages %></td>
</tr>
</table>
You could reduce the repetition later on with partials and such, but that is not so important right now.
The more important problem is that your queries at least look you could do SQL injection with them (google for blog posts about "SQL injection active record rails"). Familiarize yourself with the ActiveRecord guides a bit more, things are more safe when you do it like this:
#chosen_date = Date.parse params[:report_date]
#incoming_messages = Message.where(inbound: 't').where(created_at: #chosen_date).count
Plus you don't need to write the SQL on your own.
Chaining the .where() leads to an AND in SQL and passing Date and Time objects (and Ranges) into the where() methods are improvements in the Rails releases from the later years
This app consists of a form to submit and currently I am trying to print a few rows of a table. This is working, but unfortunately I am also getting a single long string of the entire database table attributes. There is nothing in the code that I have written (I believe) which would cause this. I fear that this is some unseen rails magic, any insight would be great!
The controller:
class StudentsController < ApplicationController
def new
#student = Student.new
end
def create
student_map = {"student_id" => params[:student_id], "student_name" => params[:student_name],
"major" => params[:major], "minor" => params[:minor], "other_information" => params[:other_information],
"class_year_id" => params[:class_year_id], "hours_st" => params[:hours], "qr_id" => qr_id,}
if (newStudentRow.save)
redirect_to action: 'index'
else
render action: 'new'
end
end
def index
#students = Student.all
end
end
The Index view:
<h1>Students#index</h1>
<p>Find me in app/views/students/index.html.erb</p>
<table>
<thead>
<tr>
<th>Student Name</th>
<th>ID</th>
</tr>
</thead>
<tbody>
<%= #students.each do |s| %>
<tr>
<td><%= s.student_name %></td>
<td><%= s.student_id %></td>
</tr>
</tbody>
<% end %>
</table>
After entering data and submitting the form, this link shows the following output:
Thanks for the help!
Change:
<%= #students.each do |s| %>
To this:
<% #students.each do |s| %>
In Ruby, each executes the block for each element AND returns the array. Having the = outputs the array, which is why you are seeing that long string.
I am creating a Blog as my college project. Now i have a table named blogs and there are 5 attributes in the table.
blog_name, blog_user, blog_id, blog_date & blog_text
Now there are saveral entries in the blog.
I need a way to fetch the whole table and show the list of blog on a single page.
That is need a way to select the whole table and print the blog names using a while loop.
This is what you're looking for:
<% Blog.all.each do |blog| %>
# code
<% end %>
I'd also advice you learning some Ruby/Rails basics.
You can do like this
In your Controller
def index
#blog = Blog.all
end
In your view(index.html.erb)
<table border=1>
<tr>
<th>Blog Name</th>
<th>Blog User</th>
<th>Blog ID</th>
<th>Blog Date</th>
<th>Blog Text</th>
</tr>
<% #blog.each do |b| %>
<tr>
<td><%= b.blog_name %></td>
<td><%= b.blog_user %></td>
<td><%= b.blog_id %></td>
<td><%= b.blog_date %></td>
<td><%= b.blog_text %></td>
</tr>
<% end %>
</table>
So,for every blog entry you will be getting all the details populated in a table view.
Is there a way to do this without javascript?
Let me explain. I have two models, users and dogs.
I'm using the index as a home page for when the users are logged in.
There is a form that searches dogs (not by any information the user enters, it's prepopulated with dog data), but the index is listing the result of my search query on page load. I'd like it to only show when the button is submitted.
I'll show some code.
controller for dog:
def index
if current_user
#user = current_user
#breed = #user.dogs.first.primarybreed
# params[:search] = #breed
#dog = Dog.search(params[:search]).sample
end
end
view:
%= form_tag dogs_path, :method => :get do %>
<%= hidden_field_tag :search, #breed %>
<%= image_submit_tag("/images/greenadd.png", size: "10x10", :name => nil) %> New Doggy Playdate!
<% end %>
<div id="dogswrap">
<h1><%= current_user.dogs[0].name %> Should Meet With...</h1>
<table>
<tbody>
<tr>
<td><%= image_tag #dog.image.url(:medium) %></td>
<td><%= #dog.name %></td>
<td><%= #dog.nick %></td>
<td><%= #dog.primarybreed %></td>
<td><%= #dog.secondarybreed %></td>
<td><%= #dog.age %></td>
<td><%= #dog.weight %></td>
<td><%= link_to "#{#dog.user.name}" %> </td>
<td><%= image_tag #dog.user.image.url(:thumb) %> </td>
</td>
</tr>
</tbody>
</table>
Model
def self.search(search)
find(:all, :conditions => ['primarybreed LIKE ?', "%#{search}%"])
end
I would like to have an if statement that shows the table only after the submit has been pushed.
If there is another way to do this, I'd appreciate it.
Thanks!
EDIT: Still working on this. May use a render..?
You can just use where in place of the way you're currently doing it find and conditions
def self.search(search)
where('primarybreed LIKE ?', "%#{search}%")
end
One thing I've learnt when using the LIKE function in development for SQLite3 and LIKE in PostgreSQL for production, was LIKE is case-insensitive in SQLite3 but not for PSQL. You would need to use ILIKE for that.
To your main question. This is how I would do it.
def index
if current_user
#user = current_user
#dogs = Dog.search(params[:search]) if params[:search].present?
end
end
For you views, start moving everything into a partial. _form.html.erb and _dog.html.erb
form
<%= form_tag dogs_path, :method => :get do %>
<%= text_field_tag :search %>
<%= image_submit_tag("/images/greenadd.png", size: "10x10", :name => nil) %> New Doggy Playdate!
<% end %>
dog
<td><%= image_tag dog.image.url(:medium) %></td>
<td><%= dog.name %></td>
<td><%= dog.nick %></td>
<td><%= dog.primarybreed %></td>
<td><%= dog.secondarybreed %></td>
<td><%= dog.age %></td>
<td><%= dog.weight %></td>
<td><%= link_to "#{dog.user.name}" %> </td>
<td><%= image_tag dog.user.image.url(:thumb) %></td>
Notice removed #dog and replaced with dog
Index view
<%= render 'form' %>
<div id="dogswrap">
<h1><%= #user.dogs[0].name %> Should Meet With...</h1>
<table>
<tbody>
<tr>
<% if #dogs %>
<%= render #dogs %>
<% end %>
</tr>
</tbody>
</table>
changed current_user.dogs[0].. to #user.dogs[0].. Also made a conditional for if the #dogs instance variable is truthy. If it is, then render will render out the _dog.html.erb partial for each dog in the #dogs collection