I'm trying to create a partial template using <%= render "/shopping/coupons/cou" %> . Not really sure where went wrong. Thanks!
This is the error message.
undefined method `model_name' for NilClass:Class
Extracted source (around line #3):
1: <h4> Coupon </h4>
2:
3: <%= form_for(#coupon, :url => shopping_coupon_path(#coupon)) do |f| %>
4: <div class="field">
5: <%= f.label :code %>
6: <%= f.text_field :code %>
this is my coupons controller
class Shopping::CouponsController < Shopping::BaseController
def cou
form_info
end
def create
#coupon = Coupon.find_by_code(params[:coupon][:code])
if #coupon && #coupon.eligible?(session_order) && update_order_coupon_id(#coupon.id)
flash[:notice] = "Successfully added coupon code #{#coupon.code}."
redirect_to shopping_orders_url
else
form_info
flash[:notice] = "Sorry coupon code: #{params[:coupon][:code]} is not valid."
render :action => 'show'
end
end
private
def form_info
#coupon = Coupon.new
end
def update_order_coupon_id(id)
session_order.update_attributes( :coupon_id => id )
end
end
#coupon is nil when the view is being rendered.
The problem might be that <%= render "/shopping/coupons/cou" %> does not go through the cou action in the controller thus form_info method does not execute and #coupon does not get assigned a value.
You have to set #coupon in the action which renders the main view (the one which has the <%= render "/shopping/coupons/cou" %> in it).
Related
I can't seem to figure why I get undefined method `email' for nil:NilClass whenever I try to call any methods on my message class.
index.html.erb messages:
<div class="callout">
<div class="messages-box">
<% #messages.each do |message| %>
<% user_status = message.user_id == current_user.id ? "reciever" : "sender" %>
<div class="<%= user_status %> callout">
<p><%= message.body %></p>
<p><%= message.user.email %></p>
</div>
<% end %>
<%= simple_form_for([#conversation, #message]) do |f| %>
<%= f.input :body %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.submit "Add Reply", class: 'button' %>
<% end %>
</div>
</div>
message controller:
class MessagesController < ApplicationController
before_action :setup_conversation
def index
#messages = #conversation.messages
#message = #conversation.messages.new
end
def new
#message = #conversation.messages.new
end
def create
#message = #conversation.messages.new(message_params)
redirect_to conversation_messages_path(#conversation) if #message.save
end
private
def setup_conversation
#conversation = Conversation.find(params[:conversation_id])
end
def message_params
params.require(:message).permit(:body, :user_id)
end
end
works fine if I remove the form or If remove the #message instance variable from the index action in the corresponding controller but I need it for the form in the index view.
This is a pretty interesting case because you're getting bit by ActiveRecord collection proxies.
In this line, you assign #messages, which is an instance of a subclass of ActiveRecord_Associations_CollectionProxy, which doesn't actually have any records from the database:
#messages = #conversation.messages
What it does have, however, is a reference to the instance of Conversation that you've already assigned to #conversation.
On the next line, you create a new instance of Message associated with the same #conversation:
#message = #conversation.messages.new
You still haven't made any SQL queries at this point. Then we get into rendering, where you call each on #messages, which triggers the query:
#message.each do |message|
...
end
Because CollectionProxy is more sophisticated than a simple AssociationRelation, it coalesces the data from your database — saved records with a User association — with the new data in the collection — your non-persisted #message.
The result is that inside of this block, the last message.user is nil, having not been set. This doesn't explode on the previous lines because Ruby is happy to render message.body (which is nil) and compare nil with foo#example.com.
I am trying to make it so that this form here will display certain fields based on the type of the website. In this case, I want it to display the form for when project.type == Website.
However I keep getting
undefined method `type' for #<Project::ActiveRecord_Relation:0x007ffe1cb543a8>
I am sure i can call .type normally because it works in the console.
Here are my files:
#views/assets/_new_asset.html.erb
<%= simple_form_for #asset do |f| %>
<% if #project.type == 'Website' %>
<%= f.input :name %>
<%= f.input :url %>
<%= f.button :submit %>
<% end %>
<% end %>
Here is my assets/controller
#controller/assets_controller.rb
class AssetsController < ApplicationController
def new
#asset = Asset.new
project = Asset.where(:project_id)
#project = Project.where(:id == project)
end
def create
#asset = current_user.assets.build(asset_params)
if #asset.save
flash[:notice] = "Asset successfully added."
redirect_to(#project, :action => 'show')
else
render(:action => 'new')
end
end
private
def asset_params
params.require(:asset).permit(:id, :type,:url, :page_rank, :rev_company ,:social_pages)
end
end
Well, you are getting back an object of ActiveRecord::Relation, not your model instance, thus the error since there is no method called type in ActiveRecord::Relation.
This should work
#project = Project.where(:id == project).first
OR
You can do like this too
<% if #project.first.type == 'Website' %>
Doing #project.first.type works because #project.first is returning the first instance of the model that was found by the where
#views/assets/_new_asset.html.erb
<%= simple_form_for #asset do |f| %>
<% if (#project.type == 'Website') %>
<%= f.input :name %>
<%= f.input :url %>
<%= f.button :submit %>
<% else %>
You Should not see this line.
<% end %>
In Controller
#controller/assets_controller.rb
class AssetsController < ApplicationController
def new
#asset = Asset.new
# As if i have no idea from where youre getting :project_id
# in your code so i changed that. add that to asset_params
# if required. Thanks!!!
#project = Project.where(id: params[:project_id]).take
end
def create
#asset = current_user.assets.build(asset_params)
if #asset.save
flash[:notice] = "Asset successfully added."
redirect_to(#project, :action => 'show')
else
render(:action => 'new')
end
end
private
def asset_params
params.require(:asset).permit(:id, :type,:url, :page_rank, :rev_company ,:social_pages)
end
end
Okay, I've been searching for a question here thats exactly the same as mine and I can't find one, so I'm forced to ask it myself. I'm following the guide on here: http://guides.rubyonrails.org/getting_started.html
I ran into this error saying: "undefined method `errors' for nil:NilClass" for my Edit Article page.
Here is my extracted source:
<h1>Editing article</h1>
<%= form_for :article, url: articles_path(#article), method: :patch do |f| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved: </h2>
And here is my trace:
app/views/articles/edit.html.erb:4:in block in _app_views_articles_edit_html_erb___778692675__618464548
app/views/articles/edit.html.erb:3:in _app_views_articles_edit_html_erb___778692675__618464548
Here is my action Controller
class ArticlesController < ApplicationController
def new
#article = Article.new
end
def edit
#articles = Article.find(params[:id])
end
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def show
#article = Article.find(params[:id])
end
def index
#articles = Article.all
end
def update
#article = Article.find(params[:id])
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
private
def article_params
params.require(:article).permit(:title, :text)
end
end
And here is my edit.html.erb
<h1>Editing article</h1>
<%= form_for :article, url: articles_path(#article), method: :patch do |f| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#article.errors.count, "error") %> prohibited this article
from being saved: </h2>
<ul>
<% #article.errors.full_messages.each do |msg| %><li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Variable Definition
Something you might want to consider, alongside Arup's answer, is the error itself:
"undefined method `errors' for nil:NilClass"
What you're getting back is an exception because you're trying to call a method on a nil class object. As Arup pointed out, this is generally caused by your calling of an #instance_variable without defining it first
I want to highlight the fact that your error says the problem is you have an undefined method for your object. Most would treat the problem as your method is undefined for some reason; in reality the problem is you don't have the object defined.
--
Fix
The way to fix the error, as pointed out by Arup is to reference the #instance variable that's defined in the edit method, like this:
#app/controllers/articles_controller.rb
Class ArticlesController < ApplicationController
def edit
#article = Article.find params[:id]
end
end
#app/views/articles/edit.html.erb
<%= #article.errors %>
Something else you will want to consider is the following:
#app/views/articles/edit.html.erb
<%= form_for #article do |f| %>
# ...
<% end %>
Yes, you have a typo with the instance variable.
<% if #article.errors.any? %>
should be
<% if #articles.errors.any? %>
Because inside the controller action #edit, you have defined #articles not #article. But it should be named #article since it's a single article. Thus keep <% if #article.errors.any? %> as it is, change the #edit method as
def edit
#article = Article.find(params[:id])
end
Remember instance variables returns nil, if you attempt to use it before defining it in Ruby. The same happened in your case. You defined #articles, but used #article, which was not defined by you before attempting to use it, thus returns nil. And nil.errors throws the error as you see.
The problem is that #article is nil (null)
In your controller, edit the new action, so it looks like this:
def new
#article = Article.new
end
Refresh the web page, and there is no more error.
Edit new action in controller
def new
#article = Article.new
end
Since your instance of article is nill.
My problem is that if I want to test the edit form I always get this exception..
Can you help me figure out the problem?
This is the error message:
undefined method `model_name' for NilClass:Class
Extracted source (around line #5):
2: <div class="row">
3: <div class="box">
4: <span id="logo">Azubiware 2.0</span><br><br>
5: <%= form_for(#bsinfo) do |f| %>
6: <% #basedate = Date.new(#bsinfo.year) %>
7: <% #basedate = #basedate.beginning_of_year %>
8: <% #basedate = #basedate.beginning_of_week %>
I have the same form going with my users table and this works properly...
class BsinfosController < ApplicationController
def index
#title = "Verwaltung Abwesehnheiten"
end
def new
#title = "Sign up"
#bsinfo = Bsinfo.new
end
def show
#bsinfo = Bsinfo.find(params[:id])
#title = #bsinfo.year
end
def create
#bsinfo = Bsinfo.new(params[:bsinfo])
if #bsinfo.save
flash[:success] = "Schedule successfull created"
redirect_to bsinfos_path
else
render 'new'
end
end
def edit
#title = "Settings"
end
def update
if #bsinfo.update_attributes(params[:bsinfo])
flash[:success] = "Profile successfull updated"
redirect_to #bsinfo
else
render 'edit'
end
end
def destroy
Bsinfo.find(params[:id]).destroy
flash[:success] = "Scheduel destroyed"
redirect_to bsinfos_path
end
end
And the link to the edit form is like
<% #bs = Bsinfo.all %>
<% #bs.each do |bsall| %>
<%= link_to "#{bsall.name}", edit_bsinfo_path(bsall), :class => "btn" %>
<% end %>
The url appears like
localhost:3000/bsinfos/17/edit
Whatever model your form is based on is being returned as nil. Make sure the #var in the controller that the form is based on is actually set to the instance of the object you want.
The snippet of code:
form_for(#bsinfo)
is generating your error most likely because #bsinfo is nil.
I'd recommend looking at your controller code and checking for the conditions under which #bsinfo can be nil.
Im getting this error:
Showing /Users/nelsonkeating/Desktop/imright/app/views/users/new.html.erb where line #4 raised:
undefined method `model_name' for NilClass:Class
Extracted source (around line #4):
4: <%= form_for(#user) do |f| %>
5: <div class="field">
6: <%= f.label :name %><br />
7: <%= f.text_field :name %>
what do i change to fix this?
#user does not exist then (Look in the error because it is saying that it is a NilClass).
You either want to do:
form_for(User.new) do |f|
or set #user in the controller;
class UsersController
def new
#user = User.new
new
end
I suggest the latter because it's a rule of thumb for MVC to not put model calls in your views.
try to view page
<%= form_for #user, :url=> {:action =>"create"} do |f| %>
in controller
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Registration successful."
redirect_to(:controller =>"user_sessions", :action =>"new")
else
render :action => 'new'
end
end
That indicates that #user is nil. Perhaps you changed the variable name from #user to something else in your controller and forgot to change it in your view? Maybe this view is being rendered in the create or update action after an error, and the variable is called something besides #user in those actions?