I'm earning rails with the guidebook, but some code does not run as expected (use Rails 4.2.6, but book was written about older version). Appreciate if you can help me.
When i load pages of any of my objects (Ads) - i see nice page with object parameters, but when I load page with list of objects - I get
NoMethodError in Ads#index
Showing /home/mei33/mebay/app/views/ads/index.html.erb where line #11 raised:
undefined method `id' for nil:NilClass
<ul>
<% for ad in #ads %>
<li><%= #ad.name %></li>
<% end %>
</ul>
my ads_controler.rb looks like that:
class AdsController < ApplicationController
def show
#ad = Ad.find(params[:id])
end
def index
#ads = Ad.all
end
end
tried to add this line of code, but not helped:
def new
#ad = Ad.new
end
maybe there is something I cannot notice? some mistake?
You should call as ad.id not #ad.id:
<ul>
<% for ad in #ads %>
<li><%= ad.name %></li>
<% end %>
</ul>
Or:
<ul>
<% #ads.each do |ad| %>
<li><%= ad.name %></li>
<% end %>
</ul>
Related
Hello I'm still fairly new to Rails but, currently I have been working on a Rails project for bit now and my last issue with it is when someone clicks on a specific recipe it only shows the very first one a user ever created. I've accessed my database through my console to see if these recipes are saving and they are but when I click on any of the links to a specific recipe it still shows the incorrect one and it won't show the recipe name either.
Here's my recipe controller
class RecipesController < ApplicationController
before_action :require_login
def show
#recipe=Recipe.find_by(params[:name])
binding.pry
end
def index
#recipes =Recipe.all
#binding.pry
end
def new
#recipe = Recipe.new
#recipe.ingredients.build(name: "name")
end
def create
#recipe = Recipe.new(recipe_params)
#recipe.save
#binding.pry
redirect_to recipes_path
end
private
def recipe_params
params.require(:recipe).permit(:id,:name,:content, ingredients_attributes: [
:recipe_id,
:user_id,
:name,
:quantity
]
)
end
end
Index Page
<h1>All Recipes</h1>
<ul>
<% #recipes.each do |recipes| %>
<li><%= link_to recipes.name, recipes %></li>
<% end %>
</ul>
Show Page
<% #recipe.name do |r| %>
<h2> <%= r.name %></h2>
<h2> <%= r.content %></h2>
<%end%>
<h3>Ingredients</h3>
<ul>
<% #recipe.ingredients.each do |ingredient| %>
<li><%= "#{ingredient.name} X #{ingredient.quantity}" %></li>
<% end %>
</ul>
Any help would be appreciated
Thank you!
In your show method it's either one of those
Recipe.find_by(name: params[:name])
# or ...
Recipe.find(params[:id])
...depending on what setup you got going in your routes, the second one is the usual Rails way of doing things.
There are a few issues with your code. In your RecipesController, change the show action code to this:
def show
#recipe = Recipe.find(params[:id])
end
In your index.html.erb view, change the code that iterates through your recipes to this:
<% #recipes.each do |recipe| %>
<li><%= link_to recipes.name, recipe %></li>
<% end %>
And finally, in your show.html.erb view, change the code to this:
<h2><%= #recipe.name %></h2>
<h2><%= #recipe.content %></h>
<h3>Ingredients</h3>
<ul>
<% #recipe.ingredients.each do |ingredient| %>
<li><%= ingredient.name %> X <%= ingredient.quantity %></li>
<% end %>
</ul>
Summary of the changes
In the show action of the RecipesController, you search for the recipe by the id passed in from the view. That id comes from this line:
<%= link_to recipe.name, recipe %>
recipe gets to_param called on it, which returns the id of that particular recipe which you then use in the show action of the RecipesController to find the correct recipe.
In the index.html.erb view, you iterate through all of the recipes, via the #recipes variable, and output each recipe. Since you are outputting each recipe, you normally use recipe instead of recipes as the block variable.
In the show.html.erb view, you don't need to iterate through all recipes because you only have one recipe from the show action of the RecipesController. That recipe is stored in the #recipe variable, so you can use that variable directly in the view.
I have sidebar in application.html.erb.
<div class="well sidebar-nav">
<h3>Rewards</h3>
<% #rewards.each do |reward| %>
<ul class="nav nav-list">
<li class="nav-header"><%= reward.title %></li>
<li><%= reward.price %></li>
<li><%= reward.image_url %></li>
<li><%= reward.details %></li>
<li><%= reward.estimated_delivery %></li>
<li><%= reward.claimed %></li>
</ul>
<% end %>
</div><!--/.well -->
I generated Rewards by: rails g scafford Rewards ....following properties.
My rewards view is working fine. but when i going on other page i get this error
undefined method `each' for nil:NilClass
I know this is because my application.html.erb is looking for #rewards in applicationcontroller and it's not there. But i dont know how to fix this issue.
If you want to have it application-wide, you should set it in before_filter of application_controller:
class ApplicationController < ActionController::Base
before_filter :set_rewards
# ...
private
def set_rewards
#rewards = #set your rewards here
end
end
I'm doing archives for my blog ,actually I'm moving from rails to sinatra because of the requirements.I'm trying the same for Sinatra
In my app.rb:
def index
#posts = Post.all(:select => "title, id, created_at", :order => "created_at DESC")
#post_months = #posts.group_by { |t| t.created_at.beginning_of_month }
end
and in Layout.erb :
<div class="archives">
<h2>Blog Archive</h2>
<% #post_months.sort.reverse.each do |month, posts| %>
<h3><%=h month.strftime("%B %Y") %></h3>
<ul>
<% for post in posts %>
<li><%=h link_to post.title, post_path(post) %></li>
<% end %>
</ul>
<% end %>
Can anyone please help me how to do it for sinatra? I'm trying the same code and I'm getting this :undefined method `sort' for nil:NilClass
You are not using Sinatra's notation for defining actions. Instead of:
def index
# your code...
end
You need to define actions like so:
get '/' do
# your code...
end
You should probably read this before continuing: http://www.sinatrarb.com/intro.html
I created a new controller called browse and this is what I have inside it
class BrowseController < ApplicationController
def index
#hashtags = Hashtag.all
end
end
I'm trying to display all of the hashtags in view using this (views\browse\index.html.erb)
<ul>
<% #post.hashtags.each do |h| %>
<li><%= h.hashtags %></li>
<% end %>
</ul>
Here's the error that I'm getting
NoMethodError in Browse#index
undefined method `hashtags' for nil:NilClass
My routes.rb
get'/browse' => 'browse#index', :as => :index
How can I fix this error to display the list in browse.html.erb?
And if I wanted to display them in descending order of date, where do I need to put that?
You should use code in index view as follows:
<ul>
<% #hashtags.each do |h| %>
<li><%= h.{field_name} %></li>
<% end %>
</ul>
Where {field_name} must be the name of field included in Hashtagm model.
You did #hashtags = Hashtag.all in the controller, while you do #post.hashtags.each in your view.
Maybe you should do #hashtags.each in your view too.
I'm trying to paginate with will_paginate in my rails app.
in my controller I have
def index
params[:per_page] ||= 25
params[:page] ||= 1
#links = Link.order('created_at DESC').page(params[:page]).per_page(params[:per_page])
end
in my view I have
<ul>
<% #links.each do |entry| %>
<li><%= link_to entry.title, entry.url %></li>
<% end %>
<ul>
<%= will_paginate #links %>
I'm getting the error
comparison of Fixnum with String failed
Extracted source (around line #8):
5: </h2>
6:
7: <ul>
8: <% #links.each do |entry| %>
9: <li><%= link_to entry.title, entry.url %></li>
10: <% end %>
11: <ul>
I have no idea why. I have tried restarting the server. Am I missing something obvious?
Thanks in advance.
I'm guessing that you have a simple "everything in params is a String" problem, that could explain why someone is trying to compare a Fixnum with a String. The page and per-page values should be Fixnums but, if they come from params, they will be strings. The easiest thing to do is to add a couple to_i calls as indicated:
def index
params[:per_page] ||= 25
params[:page] ||= 1
#links = Link.order('created_at DESC').page(params[:page].to_i).per_page(params[:per_page].to_i)
#---------------------------------------------------------^^^^
#------------------------------------------------------------------------------------------^^^^
end
The query that paginate produces won't be evaluated until you try to get something from it, that's why you don't get the error until you #links.each in your template.