Getting Started with Rails section 5.8 - SyntaxError in ArticlesController#index - ruby-on-rails

I'm doing the tutorial for RoR and am getting an exception:
SyntaxError in ArticlesController#index
"....rails/blog/app/views/articles/index.html.erb:18: syntax error,
unexpected keyword_ensure, expecting end-of-input ensure ^"
It points to line 18 of an 16 line file. index.html.erb:
<h1>Listing articles</h1>
<table>
<tr>
<th>Title</th>
<th>Text</th>
</tr>
<% #articles.each.do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
</tr>
<% end %>
</table>
The articles_controller.rb file:
class ArticlesController < ApplicationController
def index
#articles = Article.all
end
def show
#article = Article.find(params[:id])
end
def new
end
def create
#article = Article.new(article_params)
#article.save
redirect_to #article
end
private
def article_params
params.require(:article).permit(:title, :text)
end
end
Not sure where my error is. I'm using LightTable to edit the work.

In Ruby do is a keyword that denotes a block. Not a method.
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
</tr>
<% end %>
Additionally you are not properly checking if the article is valid in your create method:
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render :new # renders /app/views/articles/new.html.erb
end
end

You have a typo on your code, it should be <% #articles.each do |article| %>
<h1>Listing articles</h1>
<table>
<tr>
<th>Title</th>
<th>Text</th>
</tr>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
</tr>
<% end %>
</table>

Related

I cannot find the source of a print in Ruby on Rails website project. The array is printed sloppily above the table it is displayed in

It looks like this. The information being printed is from the table creation below it I just cannot find out how to stop it without stopping the table from being printed as well.
Here is relevant code.
My index view for the projects file
<div class="jumbotron jumbotron-fluid bg-primary">
<div class="container">
<h1 class="display-4">Hochschule München Student Projects</h1>
<p class="lead">This website holds all the student led projects along with information about each of them.</p>
</div>
</div>
<div class="jumbotron jumbotron-fluid bg-primary">
<div class="container">
<h1 class="display-4">Hochschule München Student Projects</h1>
<p class="lead">This website holds all the student led projects along with information about each of them.</p>
</div>
</div>
<h1>Listing projects</h1>
<br>
Filter by Professor
<%= collection_select(:project, :project_professor, Project.all.select(:project_professor).uniq, :project_professor, :project_professor, prompt: true) %>
<br>
<table border="1">
<tr>
<th><%= sortable "project_title", "Project Title" %></th>
<th><%= sortable "project_professor", "Professor" %></th>
<th><%= sortable "project_partner", "Partner" %></th>
<th></th>
<th></th>
<th></th>
</tr>
<%= #projects.each do |project| %>
<tr>
<td><%= project.project_title %></td>
<td><%= project.project_professor%></td>
<td><%= project.project_partner%></td>
<td><%= link_to 'Show', project_path(project) %></td>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<td><%= link_to 'Destroy', project_path(project),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br>
<%= link_to 'New project', new_project_path %>
And here is the controller file.
class ProjectsController < ApplicationController
helper_method :sort_column, :sort_direction
def index
#projects = Project.order(sort_column + " " + sort_direction); 0
end
def new
#project = Project.new
end
def create
#project = Project.new(project_params)
if #project.save
redirect_to #project
else
render 'new'
end
end
def edit
#project = Project.find(params[:id])
end
def update
#project = Project.find(params[:id])
if #project.update(project_params)
redirect_to #project
else
render 'edit'
end
end
def show
#project = Project.find(params[:id])
end
def destroy
#project = Project.find(params[:id])
#project.destroy
redirect_to projects_path
end
private
def project_params
params.require(:project).permit(:project_title, :project_semester, :project_partner, :project_professor, :project_format, :project_department, :project_description, :project_image, :project_link)
end
def sort_column
Project.column_names.include?(params[:sort]) ? params[:sort] : "project_title"
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
end
Thanks for any help! I've been having this problem for days now and cannot find the error.
<%= #projects.each do |project| %>
<tr>
<td><%= project.project_title %></td>
<td><%= project.project_professor%></td>
<td><%= project.project_partner%></td>
<td><%= link_to 'Show', project_path(project) %></td>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<td><%= link_to 'Destroy', project_path(project),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
In Erb, <%= is used to write ruby code that will produce output and <% is used to write ruby code that will not produce output such as loops or conditionals.
Try writing your loop like this and see if that helps.
<% #projects.each do |project| %>
More info here: https://guides.rubyonrails.org/action_view_overview.html#erb
change
<%= collection_select(:project, :project_professor, roject.all.select(:project_professor).uniq, :project_professor, :project_professor, prompt: true) %>
for
<% collection_select(:project, :project_professor, roject.all.select(:project_professor).uniq, :project_professor, :project_professor, prompt: true) %>
The problem is the character "=" since it tells rails that it should show this variable and shows what the query brings
Change
<%= #projects.each do |project| %>
to
<% #projects.each do |project| %>
Remove = to avoid printing the return value of each method
Hope that helps!

Rails 4.2 undefined method `total_pages' for #<ActiveRecord

I am new to Rails and I am having trouble with the will_paginated gem on my ruby app. I have searched for answers but nothing clear has been obvious.
Here is my code.
class PostsController < InheritedResources::Base
private
def post_params
params.require(:post).permit(:name, :plan)
Post.paginate(:page => params[:page], :per_page => 3)
end
end
And the index
<p id="notice"><%= notice %></p>
<h1>Listing Posts</h1>
....................
<tbody>
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= post.plan %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
</tr>
<% end %>
</tbody>
</table>
<%= will_paginate #posts %>
<br>
<%= link_to 'New Post', new_post_path %>
This is the error
undefined method `total_pages' for # ActiveRecord
I hope someone can help. Thanks very much" If I need to provide more code I will.

NoMethodError in MicropostsController#index

I cannot figure this out-
NoMethodError in MicropostsController#index
and
I have searched the web and cannot seem to make the right change. I am doing Michael Hartl's Rails Tutorial and I am in ch 2 where we do microposts.
Here's index.html.erb
Listing Microposts
<table>
<thead>
<tr>
<th>Content</th>
<th>User</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #microposts.each do |micropost| %>
<tr>
<td><%= micropost.content %></td>
<td><%= micropost.user_id %></td>
<td><%= link_to 'Show', micropost %></td>
<td><%= link_to 'Edit', edit_micropost_path(micropost) %></td>
<td><%= link_to 'Destroy', micropost, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Micropost', new_micropost_path %>
and
Microposts Controller
Class MicropostsController < ApplicationController
def index
end
def show
end
def new
end
def edit
end
def create
end
def update
end
def destroy
end
end
You are getting this error because there is no microposts instance variable in index action, in index action you should set #microposts like this:
def index
#microposts = Micropost.all
end

group_by two parametrs

In the tasks_controller, I defined:
def index
#tasks = Task.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #tasks }
end
end
I have three parameters in my table: name, task, done.
now, I want to produce:
<table>
<tr>
<th>Name</th>
<th>num of tasks</th>
<th>num tasks left</th>
</tr>
<% #tasks.group_by(&:name).each do |name, tasks| %>
<tr>
<td><%= name %></td>
<td><%= tasks.size %></td>
<td> here I want to produce the number of tasks left </td>
</tr>
<% end %>
</table>
how can I get the number of tasks left? I think it should be something like:
<% #tasks.group_by(&:name).each do |name, tasks| %>
<tr>
<td><%= name %></td>
<td><%= tasks.size %></td>
<% #tasks.group_by(name, :done => "yes").each do |name, tasks| %>
<td><%= tasks.size %></td>
<% end %>
</tr>
<% end %>
You had a good idea ;)
<% #tasks.group_by(&:name).each do |name, tasks| %>
<tr>
<td><%= name %></td>
<td><%= tasks.size %></td>
<td><%= tasks.select{ |task| task.done != 'yes' }.size %></td>
</tr>
<% end %>
tasks.select{ |task| task.done != 'yes' } : This will select the tasks where done is not yes, put it in an array and calculate its size (number of tasks not done yet).
I strongly recommend you to set your #tasks variable like following (takes much less performances: the DB does the work for you!)
# in the controller
#tasks = Task.count(:group => 'name') #instead of #tasks = Task.all
It has the same output as #tasks.group_by(...) but is much better in execution time.

ruby printing database content

I am new in Ruby.
I have to render the database structure, using tutorial i found suitable code:
File index.html.erb:
<h1>Listing tasks</h1>
<table>
<tr>
<th>Title</th>
<th>Content</th>
<th>Date From</th>
<th>Date To</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.content %></td>
<td><%= task.datefrom %></td>
<td><%= task.dateto %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, :method => :delete, :data => { :confirm => 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Now i want to group tasks by 'date from' value, probably it means that in index.html.erb i should print only dates, and clicking on the date i should call another html file that will render tasks by chosen date.
this can be like
File index.html.erb:
<h1>Listing dates</h1>
<table>
<tr>
<th>Date From</th>
<% #tasks.each do |task| %>
<tr>
<td><%= !!! IF DATE NOT PRINTED THEN PTINT IT task.datefrom %></td>
<td><%= link_to 'Edit', edit_date_path(task, date) %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Where edit_date_path(task, date) should refer me to the index_date.html.erb, where i can get selected date and print tasks according to selected date.
Maybe i can get suggestion, it will be much easier is fomebody can help me with that, as task should not be very difficult, but otherwise i can waste quite a lot of time googling.
Thanks,
Urmas.
Editing the question.
This helped a little. what i did now, i changed index.html.erb to
<h1>Listing dates</h1>
<table>
<tr>
<th>Date To</th>
<th></th>
</tr>
<% dates = Array.new %>
<% #tasks.each do |task| %>
<% if ( !dates.include?(task.dateto.strftime("%m.%d.%Y")) ) then
dates.push task.dateto.strftime("%m.%d.%Y")
%>
<tr>
<td><%= task.datefrom.strftime("%m.%d.%Y") %></td>
<td><%= link_to 'Show Date', {:action => "index", :date => task.dateto} %></td> <-- This does not work
</tr>
<%
end
%>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Where 'Show Date' link link should be made to show_date.html.erb, where is correct code for showing records when input date is passed.
I had added in controller also method
def show_date
#tasks = Task.find(params[:dateto])
#dateto = :dateto
respond_to do |format|
format.html # showdate.html.erb
format.json { render :json => #tasks }
end
end
that can be used in the not working link, to pass data to the 'Show Date' (show_date.html.erb), but i get errors all the time. The problem is with correct calling off the show_date.html.erb, code i will be able to write myself :)
Urmas
in Tasks controller:
add a method
def index_date
#tasks = Task.all
end
and create a index_date.html.erb write
<% #tasks.each do |task| %>
<tr> <td><%= task.datefrom %></td>
<td><%= link_to 'Edit', {:action => "index", :date => task.datefrom} %></td>
</tr>
<%end%>
and in the index method in the controller change
#tasks = Task.all to
#tasks = Task.find_all_by_datefrom(#{params[:date])
This will list the tasks that match the date selected and everything will be similar as it is now thereafter.
Found the solution.
It were necessary to add to routes.rb
resources :tasks do
member do
get 'showdate'
end
get "home/index"
end
add corresponding controller processing
def showdate
#task = Task.find(params[:id])
#tasks = Task.find(:all)
respond_to do |format|
format.html # showdate.html.erb
format.json { render :json => #tasks }
end
end
and to call it using (index.html.erb)
<td><%= link_to 'Show Date', showdate_path(task.id) %></td>
All further processing is already in showdate.html.erb.
Hope this helps somebody.
I AM THE BEST!!!! xD

Resources