NoMethodError in Welcome#index - Getting Started with Rails - ruby-on-rails

Screenshot Photo
Need help for this error. I can't figure out what's wrong with the code. I did research for related topics online but I can't find any solution. Below are the codes.
<!-- index.html.erb -->
<h1>Hello, Rails!</h1>
<%= link_to 'My Blog', controller: 'articles' %>
<%= link_to 'New article', new_article_path %>
<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>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<td><%= link_to 'Destroy', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
Here's the code from the controller.
# welcome_controller.rb
class WelcomeController < ApplicationController
def index
end
end
Config codes
# routes.rb
Rails.application.routes.draw do
get 'welcome/index'
resources :articles
root 'welcome#index'
end
Any help would be appreciated!

Undefined method each for nil:NilClass
The error is due to #articles is nil. You should define it in the welcome#index
class WelcomeController < ApplicationController
def index
#articles = Article.all
end
end
However you can tweak the index.html.erb to avoid such errors
<% unless #articles.blank? %>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<td><%= link_to 'Destroy', article_path(article), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
<% end %>

#Pavan's answer is correct and will solve your issue! As you getting started, I decided to write this answer to explain a little more what was happening:
You're routing root to 'welcome#index', i.e., when you hit http://localhost:300/ it you call method index from WelcomeController. We are used to call it index action from WelcomeController.
After run this method, it will (by default) render the file app/views/welcome/index.html.erb. See the pattern? The action name is the same as the file name and the controller name is the same as the folder name containing this file.
In this file you were using #articles. This is a variable that was defined in WelcomeController#index.
Your issue: this variable wasn't defined in the controller, resulting a nil object. I.e, it doesn't existed.
Solution: define this variable as #Pavan suggested.
But you could fall into the same exception again: if you haven't articles saved. To prevent this case you just need to check if #articles is nil, as #Pavan suggested too.
Hope this answer will clarify the issue and the suggestions to solve it!

Related

What is the cleanest way of implementing cancancan on my index.html.erb in Ruby on Rails?

I'm just wondering what everyone recommends doing for using cancan in their .html pages?
Just a little info on what I currently have set up...
My /app/models/ability.rb:
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, :all
end
I am using an articles_controller.rb and I set up an article model.
I am using the load_and_authorize_resource method in my articles_controller.rb
So onto my index.html.erb.
I have some CRUD options on my page and I only want some links and options such as edit and delete to be visible to the admin user.
In one part of my index.html.erb I have this link which can only be viewed by the admin.
<% if can? :create, #article %>
<%= link_to 'Post New Load Data!', new_article_path %>
<% end %>
^ This is perfect for what I want.
But I have another area on my index.html that confuses me. It goes something like this...
<% if current_user && current_user.admin? %>
<table>
<tr>
<th>Title</th>
</tr>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= link_to 'View', article_path(article) %> |</td>
<td><%= link_to 'Edit', edit_article_path(article) %> |</td>
<td><%= link_to 'Delete', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
<p>
</table>
<% else %>
<table>
<tr>
<th>Title</th>
</tr>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= link_to 'View', article_path(article) %> |</td>
</tr>
<% end %>
</table>
<% end %>
So it allows Admin to see the Edit and Delete options.
This is what I want but I am not using CanCan to do this. Is there a
way to simplify this using CanCan? That way I don't have to repeat a lot of
my sections.
I like to stick with devise's current_user.admin? because it reads nicely:
<table>
<tr>
<th>Title</th>
</tr>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= link_to 'View', article_path(article) %> |</td>
<% if current_user.admin? %>
<td><%= link_to 'Edit', edit_article_path(article) %> |</td>
<td><%= link_to 'Delete', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</table>

Rails: route helpers for nested resources

I have nested resources as below:
resources :categories do
resources :products
end
According to the Rails Guides,
You can also use url_for with a set of objects, and Rails will automatically determine which route you want:
<%= link_to 'Ad details', url_for([#magazine, #ad]) %>
In this case, Rails will see that #magazine is a Magazine and #ad is an Ad and will therefore use the magazine_ad_path helper. In helpers like link_to, you can specify just the object in place of the full url_for call:
<%= link_to 'Ad details', [#magazine, #ad] %>
For other actions, you just need to insert the action name as the first element of the array:
<%= link_to 'Edit Ad', [:edit, #magazine, #ad] %>
In my case, I have the following code which was fully functional:
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= link_to 'Show', category_product_path(product, category_id: product.category_id) %></td>
<td><%= link_to 'Edit', edit_category_product_path(product, category_id: product.category_id) %></td>
<td><%= link_to 'Destroy', category_product_path(product, category_id: product.category_id), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Obviously it is a little too verbose and I wanted to shorten it using the trick mentioned above from rails guides.
But if I changed the Show and Edit link as follows:
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= link_to 'Show', [product, product.category_id] %></td>
<td><%= link_to 'Edit', [:edit, product, product.category_id] %></td>
<td><%= link_to 'Destroy', category_product_path(product, category_id: product.category_id), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Neither of them works any more, and the pages complains the same thing:
NoMethodError in Products#index
Showing /root/Projects/foo/app/views/products/index.html.erb where line #16 raised:
undefined method `persisted?' for 3:Fixnum
What did I miss?
The way Rails is 'automagically' knowing which path to use is by inspecting the objects you pass for their classes, and then looking for a controller whose name matches. So you need to make sure that what you are passing to the link_to helper is the actual model object, and not something like category_id which is just a fixnum and therefore has no associated controller.
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= link_to 'Show', [product.category, product] %></td>
<td><%= link_to 'Edit', [:edit, product.category, product] %></td>
<td><%= link_to 'Destroy', [product.category, product], method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
I'm guessing the offending line is one of these:
<td><%= link_to 'Show', [product, product.category_id] %></td>
<td><%= link_to 'Edit', [:edit, product, product.category_id] %></td>
The product.category_id is a Fixnum and the routing can't know that a random number is supposed to map to category_id.
Use the previous URLs you had, they're more readable.

Filter paginated posts by date introduced by user (Rails)

I have the post_controller with index method like this:
def index
#posts = Post.paginate(:page => params[:page], :per_page => 3)
end
and in app / views / posts / index.html.erb i have:
.
.
.
<table>
<tr>
<th>User</th>
<th>Post</th>
<th>Date</th>
<th colspan="3"></th>
</tr>
<% #posts.each do |post| %>
<tr>
<td><%= post.user.id %></td>
<td><%= post.text %></td>
<td><%= post.created_at %></td>
<td><%= link_to 'Show', post_path(post) %></td>
<% if can? :update, post %>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<% end %>
<% if can? :destroy, post %>
<td><%= link_to 'Destroy', post_path(post),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
<%= will_paginate #posts %>
</table>
So i want a field in this view, where an user can input a date and the view shows all posts wich were created on that date onwards. (Posts date > date_by_user). I tried with "where" method but i couldnt. I dont want to use any gem. So, what is the best and simple way to do that?
You can search records in index method like below.
date_to_search = Date.parse('2015/1/1')
Post.where(
'created_at>=? and created_at<=?',
date_to_search.beginning_of_day
)
created_at is saved as UTC in rails, so you need to specify datetime. Not only date, to get correct data in your local time.

rails path helper doesnt work

Hello im learning Rails on my testing app and i have this code
<% #categories.each do |category| %>
<tr>
<td><%= category.name %></td>
<td><%= link_to 'Show', backend_category %></td>
<td><%= link_to 'Edit', edit_backend_categories(category) %></td>
<td><%= link_to 'Destroy', backend_category, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
and Rake routes shows me this
home_index GET /home/index(.:format) home#index
root / home#index
contact /contact(.:format) home#contact
backend_root /backend(.:format) backend/admin#index
backend_categories GET /backend/categories(.:format) backend/categories#index
POST /backend/categories(.:format) backend/categories#create
new_backend_category GET /backend/categories/new(.:format) backend/categories#new
edit_backend_category GET /backend/categories/:id/edit(.:format) backend/categories#edit
backend_category GET /backend/categories/:id(.:format) backend/categories#show
PUT /backend/categories/:id(.:format) backend/categories#update
DELETE /backend/categories/:id(.:format) backend/categories#destroy
but im getting error that backend_category doesnt exist
here is image
http://www.nahraj-obrazek.cz/?di=213711395092
whats wrong ? Thank you
You must add _path to your link_to helper url, like so
<% #categories.each do |category| %>
<tr>
<td><%= category.name %></td>
<td><%= link_to 'Show', backend_category_path(category) %></td>
<td><%= link_to 'Edit', edit_backend_category_path(category) %></td>
<td><%= link_to 'Destroy', backend_category_path(category), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Following Luis answer, any show path needs a reference to an object. So I believe it should be
<td><%= link_to 'Show', backend_category_path category %></td>
Which can also be written as:
<td><%= link_to 'Show', category %></td>

undefined method `map' for nil:NilClass in Rails with Paperclip

This will be my last question for today (sorry if I'm asking too fast)
I'm getting the error undefined method 'map' for nil:NilClass
It says the problem is on this line: <td><%= image_tag #map.map.url %></td>
The whole index code is below:
<h1>Listing maps</h1>
<table>
<tr>
<th>Carname</th>
<th>Map</th>
<th>Criticalcomponentlocations</th>
<th>Warnings</th>
<th>Additionalinfo</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #maps.each do |map| %>
<tr>
<td><%= map.carname %></td>
<td><%= image_tag #map.map.url %></td>
<td><%= map.criticalcomponentlocations %></td>
<td><%= map.warnings %></td>
<td><%= map.additionalinfo %></td>
<td><%= link_to 'Show', map %></td>
<td><%= link_to 'Edit', edit_map_path(map) %></td>
<td><%= link_to 'Destroy', map, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Map', new_map_path %>
Maps Controller, Index:
def index
#maps = Map.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
In your #maps.each loop, you're trying to access a (probably) non-existent #map instance variable when you should be accessing the map variable that is local to your loop.
Try this instead:
<% #maps.each do |map| %>
<tr>
...
<td><%= image_tag map.map.url %></td>
...
</tr>
<% end %>
The variable you wish to use, map, is not an instance variable. It is a local variable, so you should use 'map.url' instead of '#map.map.url'
Your line of code <td><%= image_tag #map.map.url %></td> uses an instance variable #map, but you're inside the scope of the enumerator <% #maps.each do |map| %>. You should use the map.url local variable instead of #map.map.url.

Resources