I have a shopping cart button in the _navbar.html.erb partial of my app (rendered in my application.html.erb layout) that uses the variable #current_order.
My application_controller.rb defines #current_order:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :set_order
private
def set_order
#current_order = Order.find(session[:order_id])
rescue ActiveRecord::RecordNotFound
#current_order = Order.create!
session[:order_id] = #current_order.id
#current_order
end
end
The navbar looks like this:
...
<li>
<button type="button" class="btn btn-invisible position-relative">
<%= simple_form_for(#current_order, html: { id: "goToCart" }) do |f| %>
<%= f.hidden_field :move_to_checkout, value: false %>
<%= button_tag( :class => "btn-invisible mt-2") do %>
<i class='fas fa-shopping-cart'></i>
<% end %>
<% end %>
<span class="position-absolute translate-middle badge rounded-pill bg-danger">
<%= #current_order.order_number_of_items %>
</span>
</button>
</li>
...
On my empty root page, it renders just fine, but on pages that deal with an #order or with #current_order, I get an error:
undefined method `model_name' for nil:NilClass
This is called on the simple_form_for(#current_order) line of the navbar partial.
Can anyone see why some pages aren't getting #current_order as designated in the application_controller?
In your order-related controller(s) you probably have another before_action named set_order - and that'll overwrite the one in ApplicationController. Rename one of 'em.
Related
I'm actually making an ecommerce web app which has a User, Category, Book and Comment models. Everything is working nice, but when I try to comment in one of the book, it gives a 400 error. I really need you to help me out. https://github.com/felixpro/Book-app this is my repository.
This is my CommentsController
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
book = Book.find(params[:comment][:book_id])
comment = book.comments.build(comment_params)
comment.user = current_user
if comment.save
redirect_to book_path(#book)
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
end
This is the comment view partial,
<% if signed_in? %>
<div class="card bg-light new-comment">
<div class="card-body">
<p class="font-weight-bold">Deja tu comentario:</p>
<%= form_for #book.comments.build do |f| %>
<%= f.hidden_field :book_id, value: #book.id %>
<div class="form-group">
<%= f.text_area :body, rows: 4, class: "form-control" %>
</div>
<div class="text-right">
<%= f.submit "Comentar", class: "btn btn-primary" %>
</div>
<% end %>
</div>
</div>
<% else %>
<div class="card bg-light mt-5">
<div class="card-body">
<p class="card-text text-center lead"><%= link_to "Regístrate", new_user_registration_path %> o <%= link_to "Ingresa", new_user_session_path %> para comentar</p>
</div>
</div>
<% end %>
Here are the routes
Rails.application.routes.draw do
devise_for :users
root 'books#index'
resources :books
resources :comments, only: [:create]
end
The error say
This is a pictures showing the error message
The error you mentioned is linked to the fact that you have a special invisible character (non-breaking space) at line 9 and 14 in your CommentsController. This is why you get the
NameError (undefined local variable or method `' for ...)
This often happens when you hit an additional key at the same time you hit the space bar (cmd + space bar on MacOS). Delete those empty lines and type the enter key again to clear the character.
Then the other answer is right, you'll have have to update your book variable name.
You have referred to #book when the variable is a local book. Use # at the beginning of the line 6:
#book = Book.find(params[:comment][:book_id])
I am trying to put a drop down in my navbar where users can click on links to the different stone show pages. With the code I have in now I am getting a NoMethodError private method `each' called for nil:NilClass.
I am pretty sure this private method error is coming up because I am putting this code in my navbar which is in my application.html.erb rather then in the stone model. Could someone point me in the right direction as to where I should define methods for the navbar? Or if there is something else I should be doing instead?
Here is what I have attempted so far:
application.html.erb
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu">
<% #stones.each do |stone| %>
<li> <%= link_to stone_url do %>
<%= stone.name %>
<% end %>
</li>
<% end %>
</ul>
</div>
application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_order
def each
#product = Product.all
end
def current_order
if !session[:order_id].nil?
Order.find(session[:order_id])
else
Order.new
end
end
end
you are calling .each on the var #stones and not on your controller, views cant call methods from controllers, unless they are helper methods. try to use a before_filter in your controller that will set your #stones and remove that each method from the controller
Just replace #stones.each to Stone.all.each.
Because there will be somewhere using var #stones, you should not define #stones on your application_controller.rb.
I might've erased my user information (:maker_id, :name, and :password) when I did rake db:reset in terminal, so now going to 'localhost:3000' '/' gives me this error:
ActiveRecord::RecordNotFound in PagesController#home
Couldn't find Maker with 'id'=1
Extracted source (around line #7):
6 def current_user
7 #current_user ||= Maker.find(session[:maker_id]) if session[:maker_id]
8 end
9 helper_method :current_user
My application controller has:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def current_user
#current_user ||= Maker.find(session[:maker_id]) if session[:maker_id]
end
helper_method :current_user
def authorize
redirect_to '/' unless current_user
end
end
My pages controller has an empty
def home
end
My pages home.html.erb view has:
<div class='text-center'>
<h1>Welcome to venture</h1>
<br><br>
<%= link_to "Signup", '/signup', class: 'btn btn-success' %> or
<%= link_to "Login", '/login', class: 'btn btn-primary' %>
</div>
My layouts application.html.erb view has:
<body class="containter">
<div class='pull-right'>
<% if current_user %>
Logged in as <%= current_user.name %> | <%= link_to "Logout", '/logout' %>
<% else %>
<%= link_to "Signup", '/signup'%> or <%= link_to "Login", '/login' %>
<% end %>
</div>
<h1><%= link_to 'venture', '/' %></h1>
<% flash.each do |type, message| %>
<div class="alert alert-info fade in">
<button class="close" data-dismiss="alert">×</button>
<%= message %>
</div>
<% end %>
<%= yield %>
</body>
It used to work before the db:reset which runs db:drop db:setup I believe. Usually I would just create users through the signup page but now I cannot get there.
Any insight is appreciated.
These records are not available any more - when db:drop was executed, all of them have been removed. The operation can not be undone and at the moment the only options you have is to restore db either manually or automatically if you have access to its backup.
Run rake db:setup to recreate your database. Then create a new user.
Checkout this answer to see the differences between various rake db commands
I'm trying to put some code in a partial from my show page in /events. The code works fine when I use it in my show page, but when i extract it to a partial I'm getting a No Method Error
undefined method `event' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_PaperTrail_Version:0x007f4368823a68>
versions/_version.html.erb
<% cache version do %>
<div class="feed-item">
<h4>
<%= link_to version.item.name, version.item %>
<small>
<%= version.event + "d" %> by <%= link_to User.find(version.whodunnit).username, User.find(version.whodunnit) %>
</small>
</h4>
<ul class="list-unstyled">
<% version.changeset.each do |data| %>
<li>
<strong><%= data[0].capitalize %>:</strong>
<% if data[1][0].present? %><p class="red">- <%= data[1][0] %></p><% end %>
<p class="green">+ <%= data[1][1] %></p>
</li>
<% end %>
</ul>
</div>
<% end %>
show.html.erb
<%= render :partial => '/versions/version', :object => #versions %>
events controller
def show
#versions = #event.versions
end
events model
has_paper_trail
Any idea how i could put my code in a partial instead of having it inside my show view? Thanks.
EDIT:
I still get a No Method Error
undefined method `item' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_PaperTrail_Version:0x007f43688ee1a0>
events_controller.rb
before_action :set_event, only: [:show, :update, :destroy]
def set_event
#event = Event.find(params[:id])
end
Do you have defined the #eventvariable in the eventscontroller?
The #event.versions method has to be called on an actual event object.
For example
def show
#event = Event.find(1)
#versions = #event.versions
end
I've got a controller method:
def latest_blogs
#latest_blogs = BlogEntry.all.order('dato DESC').limit(4)
end
A root html.erb file which acts as my home page:
<div class="body-box">
<div class="body-content">
<%= render :partial => 'blog_list' %>
</div>
</div>
The blog_list partial:
<div class="blog-list">
<%= latest_blogs.each do |blog| %>
<%= render :partial => "blog_preview", locals: {blog: blog} %>
<% end %>
</div>
And the blog_preview partial which is just a stub for now:
<div class="blog-preview">
<%= blog.title %>
</div>
My routes.rb entries:
resources :blog_entries
root :to => 'home#blog_home', :as => 'root'
How can I tell my app when it loads the root page to present latest_blogs? Thanks.
I would start with: this method should not be in the controller. Put it in a model instead
class BlogEntry < ActiveDirectory::Base
def self.latest (n = 4)
all.order('dato desc').limit(n)
end
Then just use it as:
BlogEntry.latest
Note that this method will also be available on relations:
user.blog_entries.latest(1) #=> returns last user blog entry
You can declare the latest_blog as helper method. Please try the following:
class BlogsController < ApplicationController
def latest_blogs
#latest_blogs = BlogEntry.all.order('dato DESC').limit(4)
end
helper_method :latest_blogs
end
Is latest_blogs your actual controller action, or is it just some method you're exposing to the view? If it's just some method you're exposing then you should make it a helper method.
def latest_blogs
#latest_blogs ||= BlogEntry.all.order('dato DESC').limit(4)
end
helper_method :latest_blogs
Note that I changed the = to ||= in here. I think that's better in this case so that if you happen to call the helper multiple times then it won't re-evaluable it repeatedly.
And FYI, you can also clean up your markup code a little bit. Your root html file could do:
<div class="body-box">
<div class="body-content">
<div class="blog-list">
<%= render partial: 'blog_preview', collection: latest_blogs %>
</div>
</div>
</div>
Then _blog_preview.html.erb:
<div class="blog-preview">
<%= blog_preview.title %>
</div>