I have this error when loading index.html.rb.
undefined method `time_series_path' for #<#<Class:0x007f6aac0d2a28>:0x007f6aac0d1358>
In routes.rb I have
namespace :viewer do
resources :time_series
end
In the TimeSeriesController I have
class Viewer::TimeSeriesController < ApplicationController
def show
#time_series = TimeSeries.find(params[:id])
end
def index
#time_series = TimeSeries.all.paginate(:page => params[:page], :per_page => 20)
end
end
In the index.html.rb I have
<h1>Listing of time series</h1>
<table >
<tr>
<th>Kind</th>
<th></th>
</tr>
<% #time_series.each do |t| %>
<tr>
<td><%= t.kind %></td>
<td><%= link_to 'Show', t %></td>
</tr>
<% end %>
</table>
<%= will_paginate #time_series %>
The error occurs for the link_to 'Show' line.
Any ideas on how to resolve this? Thanks.
If you use a namespace, the namespace becomes part of the route name.
viewer_time_series_path
not
time_series_path
To double check, you can print out the list of all the routes
rake routes
and grep to immediately check the name
rake routes | grep time_series
In your code, you either pass the namespace as array in the link_to helper along with the object
<%= link_to 'Show', [:viewer, t] %>
or (I prefer this solution) you write the corresponding path explicitly.
Related
I am trying to display all the metrics in a table format with an edit option. But, I end up with the below error
In Index view, I am able to see all the data. But when I click on edit link, it is not redirecting to edit view where I have different columns to be showed.
index view:
<%= form_for :metrics_controller, url: metrics_path(#metric), method: :get do |f| %>
<table id="metrics">
<thead>
<tr id="AllMetricColumnNames">
<th id="CommentsColumn">Comments</th>
<th id="EditColumn">Edit</th>
</tr>
</thead>
<% #metricAll.each do |data| %>
<tr id="AllMetricValues">
<td id="Comments"><%= data.Comments %></td>
<td id="EditButton"><%= link_to "Edit", edit_metric_path(#metricAll) %></td>
<% end %>
</tr>
</table>
<% end %>
Controller:
class MetricsController < ApplicationController
def index
#metricAll = Metric.all
end
def show
#metric = Metric.find(params[:id])
end
def edit
#metric = Metric.find(params[:id])
end
private def post_params
params.require(:metric).permit(:Metric, :Comments)
end
end
routes:
root 'metrics#index'
get 'index' => 'metrics#index'
get 'edit' => 'metrics#edit'
resources :metrics
You're passing ALL the metrics for the edit route. Move from
<td id="EditButton"><%= link_to "Edit", edit_metric_path(#metricAll) %></td>
to
<td id="EditButton"><%= link_to "Edit", edit_metric_path(data) %></td>
data is the current metric in your code
According to your screenshot, the error is within the model.
Also, as mentioned by others, you should remove those get routes as the resources :metrics will generate the necessary routes for all your CRUD actions a.ka. for the index, show, edit, new, create, update, destroy.
My guess is that the metric.rb file has a belongs_to :automated_thresholding relationship but the metrics database table is missing the field automated_thresholding_id.
You should create a migration to add that field
add_reference :metrics, :automated_thresholding
I have a rails application which is not routing as I expected. The search method in the controller is rending show. I've cut down the code to the minimal components and I am posting them here as suggested.
Rails.application.routes.draw do
resources :backups
get 'backups/search' => 'backups#search'
resources :components
resources :backup_media
end
class Component < ActiveRecord::Base
has_many :backups
has_many :backup_media, :through => :backups
end
class BackupMedium < ActiveRecord::Base
has_many :backups
has_many :components, :through => :backups
end
class Backup < ActiveRecord::Base
belongs_to :component
belongs_to :backup_medium
# value to match either the name of the component or backup_medium
def self.search(value)
tables = "backups, components, backup_media"
joins = "backups.backup_medium_id = backup_media.id and components.id = backups.component_id"
c = find_by_sql "select * from #{tables} where components.name like '%#{value}%' and #{joins}"
b = find_by_sql "select * from #{tables} where backup_media.name like '%#{value}%' and #{joins}"
c.count > 0 ? c : b
end
end
class BackupsController < ApplicationController
def search
#backups = Backup.search(params[:search])
render 'index'
end
def index
#backups = Backup.all
end
def show
# this would normally be the code to show an individual backup
# but I'm re-using the code from index because the routing is broken
#backups = Backup.all
end
end
views/backups/_search.html.erb
<%= form_tag backups_search_path, :method => 'get' do %>
<%= label_tag(:search, "Search for:") %>
<%= text_field_tag :search, params[:search], {:placeholder => 'Component or Media' }%>
<%= submit_tag "Search", :name => nil %>
<% end %>
views/backups/index.html.erb
<h1>Listing Backups</h1>
<p id="notice"><%= notice %></p>
<%= render :partial => 'search' %>
<table>
<tr>
<th>id</th>
<th>component_id</th>
<th>backup_medium_id</th>
</tr>
<% #backups.each do |backup| %>
<tr>
<td><%= backup.id %></td>
<td><%= backup.component.name %></td>
<td><%= backup.backup_medium.name %></td>
</tr>
<% end %>
</table>
views/backups/show.html.erb is copied from index.html.erb since it is incorrectly receiving the search results
<h1>Show Backup</h1>
<p id="notice"><%= notice %></p>
<%= render :partial => 'search' %>
<table>
<tr>
<th>id</th>
<th>component_id</th>
<th>backup_medium_id</th>
</tr>
<% #backups.each do |backup| %>
<tr>
<td><%= backup.id %></td>
<td><%= backup.component.name %></td>
<td><%= backup.backup_medium.name %></td>
</tr>
<% end %>
</table>
Suggestions on improving the search method will be welcomed.
As mentioned above, after the search is executed, the show.html.erb is rendered instead of search.html.erb
For a working demo (with better code thanks to suggestions here) see
https://github.com/pamh09/rails-search-demo
You do not have a backups_search_path in your routes, therefore it is treating search in the query string as an id and thus rendering show.html.erb, so try
get 'backups/search' => 'backups#search', as: :backups_search
In debugging I found that rails consistently routed to the wrong view when it was unhappy with the return object coming from the model.
I am making a resume application to list my employment history, education history and other responsibilities. This is my first rails application on my own without a tutorial, but much of what I do is just following the same actions. All the code is here: https://github.com/victorman/portfolio
Quick summary. I ajaxed my app a bit, and got it to work. But I had a template with the exact same html as part of a view, so I replaced that portion with a render :partial.... The result was twice the html as before. Below is a more detailed description of what I did to the app.
I made two scaffolds, one for Jobs and one for Categories. Jobs has a foreign key to categories.
I made the Jobs view list a link for each category. The jobs#index controller then only finds the rows in the jobs table for that category.
Then I decided to throw some ajax in there so that clicking a link would only reload the relevant data. I added a respond_to at the end of the jobs#index method.
def index
#find which jobs to display based on category_id in the url params
#if no category_id param is given default to 1
unless params.has_key? :category_id
#jobs = Job.find(:all, :conditions => {:category_id => 1})
else
#jobs = Job.find(:all, :conditions => {:category_id => params[:category_id]})
end
respond_to do |format|
format.html
format.js #index.js.erb
end
end
I made a index.js.erb file that retrieves the new data and replaces the old.
var jobs = $("<%= escape_javascript(render(:partial => #jobs))%>").hide();
$("#jobs_table").replaceWith(jobs);
$("#jobs_table").fadeIn();
I added remote: true to the links in the jobs index.html.erb file.
<ul>
<% Category.all.each do |category| %>
<li><%= link_to category.name, { :controller => "jobs", :category_id => "#{category.id}" }, :class => "category_link", remote: true %></li>
<% end %>
</ul>
And I made the template partial where the jobs were displayed. it would never find _jobs.html.erb so i had to name it _job.html.erb
<tbody id="jobs_table">
<% #jobs.each do |job| %>
<tr>
<td><%= job.organization %></td>
<td><%= job.location %></td>
<td><%= job.details %></td>
<td><%= job.start_date %></td>
<td><%= job.end_date %></td>
<td><%= link_to 'Show', job %></td>
<td><%= link_to 'Edit', edit_job_path(job) %></td>
<td><%= link_to 'Destroy', job, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
after all that it worked but I still hadn't DRY'd up the code so I removed the repeated section from index.html.erb which is in _job.html.erb (as shown above) and replaced it with this.
<%= render :partial => #jobs %>
and now it gives me two identical <tbody> tags with id="jobs_table". Why is this giving duplicate data?
You've got a lot to fix...
Create a nested route in your routes.rb:
resources :jobs
resources :categories do
resources :jobs
end
index.html.erb:
<h1>Listing jobs</h1>
<div>
<ul>
<% Category.all.each do |category| %>
<li><%= link_to category.name, category_jobs_path(category),
class: "category_link", remote: true %></li>
<% end %>
</ul>
</div>
<table>
<thead>
<tr>
<th>Organization</th>
<th>Location</th>
<th>Details</th>
<th>Start date</th>
<th>End date</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody id="jobs_table"><%= render partial: #jobs %></tbody>
</table>
<br/>
<%= link_to 'New Job', new_job_path %>
the index of jobs_controller.rb can (should) be refactored to:
class JobsController < ApplicationController
def index
#jobs = Job.where(category_id: params[:category_id] || 1)
respond_to do |format|
format.html
format.js
end
end
end
and the index.js.erb response also should be refactored to:
$("#jobs_table").html("<%= escape_javascript(render partial: #jobs) %>")
$("#jobs_table").fadeIn()
there are some naming issues which should be more pregnant like:
jobs instead of jobs_table
and
category instead of category_link
Also trying to find a Job belonging to Category with 1 is odd. Deal with a different response than a default Category with id 1 (hard coded ids are one of the worst things you can do).
The div around the Categories list is useless (keep your rendered HTML slim and readable).
The problem is due to not understanding when rails manipulates singular vs plural.
Calling render partial: #jobs automagically goes out to the partial _job.html.erb for each element in #jobs. But then the partial goes through each element again because of #jobs.each do |job|.
To fix it, in the render line, replace #jobs with "jobs" and rename _job.html.erb to _jobs.html.erb.
Alternatively, save a step by just replacing #jobs with "job" and keep the template name _job, but this reinforces an incorrect naming scheme.
index.html.erb:
<tbody id="jobs"><%= render partial: "jobs" %></tbody>
index.js.erb:
$("#jobs").html("<%= escape_javascript(render(partial: 'jobs'))%>")
Now it will just search literally for the _jobs template (_jobs.html.erb) and render it once as opposed to going to the singular version of the name and rendering that many times.
I have a controller models_controller.rb as following:
class ModelsController < ApplicationController
def list
#models=["A","E","M","I"]
end
def get_config
Rails.logger.info(params[:model_id])
//some logic based on params[:model_id] value
end
end
The corresponding list.html.erb is as follows:
<table>
<thead>
<tr>
<th>Model</th>
<th></th>
</tr>
</thead>
<tbody>
<% #models.each_with_index do |model, index| %>
<tr>
<td><%= model %></td>
<td><%= button_to "view", {:controller => :models, :action => :get_config, :model_id => index }, :method => :get %></td>
</tr>
<% end %>
</tbody>
</table>
Each row of this table has a button, where upon clicking, I am passing the index of the element. But I am not been able to access it in the get_config method. Logger is printing an empty string. routes.rb is as follows:
DemoApp::Application.routes.draw do
get "models/list"
get "models/get_config"
get "models/list/:model_id" => "models#get_config"
end
What am I doing wrong? I am not able to figure that out.
Rails routes are matched in the order they are specified. So get "models/get_config" is catching the request before get "models/list/:model_id" => "models#get_config". Try changing the order to this:
DemoApp::Application.routes.draw do
get "models/list"
get "models/list/:model_id" => "models#get_config"
get "models/get_config"
end
I'd like to learn how to use the methods defined in the controller in the index page.
I'm trying to implement "like" button on my blog.
PostController
def like
#post = Post.find(params[:id])
#post.like += 1
#post.save
end
In the index where all the posts are listed, I tried something like this.
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= post.created_at.strftime("%Y/%m/%d, %I:%M%p") %></td>
<td><%= post.view %></td>
<td><%= link_to 'like', like_post_path %></td>
<td>hate</td>
</tr>
<% end %>
I got the idea by looking at the code,
<%= link_to 'make a new post', new_post_path %>
<%= link_to 'Edit', edit_post_path(post) %>
I thought the way to use methods in the controller in the index page was
(method in PostController)_post_path, but it seems I got it wrong.
undefined local variable or method `like_post_path'
I've also tried like(post).
My ultimate goal is to make this function as an ajax function, so I expected it to be a form like
<% link_to_function 'like', like_post, remote: true %>
What's the right way of using the method "like" in this case?
You'd need to define a named route to make this work. Like:
# in config/routes.rb
resources :posts do
member do
get 'like'
end
# OR
get 'like', :on => :member
end
# in `rake routes` this would show up as:
like_post GET /posts/:id/like(.:format) posts#like
# you'd reference in a view like:
like_post_path(#post)