this is my post_controller
def index
#posts = Post.all.page(params[:page]).per(2)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #posts }
end
end
this is /views/posts/index
<%= paginate #posts %>
and i recive:
NoMethodError in PostsController#index
undefined method `page' for #
I saw many themes with the same error and solution:
Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)
but where should i put this?
You can put it in your controller
#posts = Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)
But you also could do this:
#posts = Post.page(params[:page]).per(2)
Related
Can't figure out what's going on as I try to add dirt simple blog capability to my website. Starter app I'm using is pre-configured for HAML and I'm an even bigger HAML n00b than Rails n00b, so I'm seriously struggling.
When I add this to my pages/home.html.haml:
%h1= I18n.t('brand.name')
%p
= I18n.t 'brand.name'
- #posts. each do |post|
= render 'posts/post', post: post
I get:
undefined method `each' for nil:NilClass
I can't figure it out... I thought Ruby had an "each" method built it? Why isn't it passing any class in?
Here's the _post.html.haml partial it's trying to render:
%p
%h2
= link_to post.title, post
%p
- if post.kind == 'image'
= image_tag post.content, style: "width: 100%"
- else
= simple_format post.content
%p.text-muted
%small
Posted on #{post.created_at.to_formatted_s(:long)}
And the controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all
end
def show
#post = Post.find(params[:id])
end
def new
#post = Post.new
end
def edit
end
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
else
format.html { render action: 'new' }
end
end
end
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
else
format.html { render action: 'edit' }
end
end
end
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :kind, :content)
end
end
And the model is empty, just:
class Post < ActiveRecord::Base
end
I copy/pasted most of this code from a working blog example I built in a tutorial and it works fine in that app.
I suspect it has something to do with PSQL (in this app) versus SQLite (in the example app). In rails console, trying it gives the same error:
[3] pry(main)> post = post.first
NoMethodError: undefined method `first' for nil:NilClass
[4] pry(main)> posts = post.each
NoMethodError: undefined method `each' for nil:NilClass
[5] pry(main)> posts = Post.each
NoMethodError: undefined method `each' for Post (call 'Post.connection' to establish a connection):Class
from /Users/troot/.rvm/gems/ruby-2.1.3/gems/activerecord-4.1.6/lib/active_record/dynamic_matchers.rb:26:in `method_missing'
I don't understand why the methods that I think should be working are not working here. Thanks so much for any help you can give.
In this line:
- #posts. each do |post|
there is a space between #posts and each. There should be no space in between as each is a method and you are explicitly calling it using the . operator on #posts object.
Then in console you are doing:
post = post.first
It should be:
post = Post.first
The class name should always be in capital.
And in the console if you need to run each then you need to do Post.all.each you can use each directly on class.
Try correcting this and then check. Hope this helps.
I thought that adding #links=Link.all to my controller would fix this problem.
I did make sure that I have valid entries in my Link DB by looking at Link.count=6
I am getting the following error:
NoMethodError in Pages#index
Showing /Projects/reddit_on_rails/app/views/pages/index.html.erb where line #6 raised:
undefined method `each' for nil:NilClass
<ul>
<% #links.each do |link| %>
<li>link.url</li>
<li>link.title</li>
<% end %>
My controller:
class LinksController < ApplicationController
#Added #links =Link.all did not solve the problem
def index
#links = Link.all
end
def show
end
def new
#link = Link.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #link }
end
end
def create
#link = Link.new(link_params)
if #link.save
#render "new"
redirect_to "/"
else
# This line overrides the default rendering behavior, which
# would have been to render the "create" view.
render "new"
end
end
private
def link_params
params.require(:link).permit(:title,:url)
end
end
According to your description, you got following error message
NoMethodError in Pages#index
Showing /Projects/reddit_on_rails/app/views/pages/index.html.erb where line #6 raised:
According to error message you have problem in Pages controller inside index method. So you need to fix the problem inside Pages controller not inside Links controller.
Do you have method called index inside your Pages controller?
#links is nil because you are not setting it anywhere in your controller with something like #links = Link.all.
You cannot call each on nil.
What view are you in? Assuming index.html.erb.
in your controller, try adding
def index
#link = Link.all
end
If that doesn't work, verify you have any links at all. In terminal instead of typing rails server type
rails console
Link.all
If that comes back as [] then you don't have any in your database.
I've hit a snag with my college project regarding the use of the Sunspot search gem and will_paginate. I've been using sunspot in my project index controller and it was working fine but when I added pagination to the same index it created a problem. I cant seem to have both the search and pagination at the same time.
This gives me the pagination (see below):
def index
#projects = Project.all
#projects = Project.paginate :per_page => 4, :page => params[:page]
respond_to do |format|
format.html # index.html.erb
format.json { render json: #projects }
end
end
This gives me my search index (see below):
def index
#projects = Project.all
#search = Project.search do
fulltext params[:search]
end
#projects = #search.results
respond_to do |format|
format.html # index.html.erb
format.json { render json: #projects }
end
end
But when I add the pagination it doesn't work/display (see below):
def index
#projects = Project.paginate :per_page => 4, :page => params[:page]
#search = Project.search do
fulltext params[:search]
end
#projects = #search.results
respond_to do |format|
format.html # index.html.erb
format.json { render json: #projects }
end
end
The search still works but the pagination doesn't appear...
Any ideas how I get them both working together?
Many Thanks!
Answering my own question here, never occured to me to add in IF and ELSE to separate the actions in the def index....
This works perfectly...
if params[:search]
#search = Project.search do
fulltext params[:search]
end
#projects = #search.results
else
#projects = Project.all
#projects = Project.paginate(:page => params[:page], :per_page => 4)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #projects }
end
I have a database of objects (tools) in my Ruby on Rails project. When I use "rails dbconsole" and
select * from tools;
it returns a whole list of tool objects. But when I try to view the following page, it gives me an error.
Page:
<!DOCTYPE html>
<html lang="en">
<%= stylesheet_link_tag "tools", :media => "all" %>
<body>
<%= #tools.each do |tool| %>
<%= link_to(tool(image_tag.image_url)) %>
<% end %>
</body>
</html>
Error:
undefined method `each' for nil:NilClass
When I change the code to add an if statement against nil objects, the page works (without displaying any tools).
<% if #tools.nil? %>
<% else %>
<%= #tools.each do |tool| %>
<%= link_to(tool(image_tag.image_url)) %>
<% end %>
<% end %>
So it seems like #tools doesn't have any values in it, but when I look at it in the dbconsole, there are tools there. I can't figure this out, and I've spent the past few days googling for answers, so any and all ideas would be welcome!
EDIT: Added tools_controller.rb
class ToolsController < ApplicationController
before_filter :check_authentication
def check_authentication
unless session[:user_id]
session[:intended_action] = action_name
session[:intended_controller] = controller_name
redirect_to new_session_url
end
end
def new
#tool = Tool.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #tool }
end
end
def show
end
def index
#tools = Tool.all
end
# GET /tools/1/edit
def edit
#tool = Tool.find(params[:id])
end
# POST /tools
# POST /tools.json
def create
#tool = Tool.new(params[:tool])
respond_to do |format|
if #tool.save
format.html { redirect_to #tool, :notice => 'tool was successfully created.' }
format.json { render :json => #tool, :status => :created, :location => #tool }
else
format.html { render :action => "new" }
format.json { render :json => #tool.errors, :status => :unprocessable_entity }
end
end
end
end
Loading #tools in a before_filter for every action as #nbarraille has suggested is a bad idea, because there are many (probably most) actions where you will definitely not need the full set of tools (e.g. create and destroy). The line #tools = Tool.all hits your database so you should minimize the number of times you use it.
For the case you have here, you only need to change your show action to get this to work:
def show
#tools = Tool.all
end
However, note that normally the show action is for displaying a single resource (tool), not the whole list of resources (which is normally done in the index action). It looks like you're deviating from the normal way of doing things, is there any particular reason why?
In order for the #tools variable to be accessible from your view, you need to declare it in your controller, like this:
#tools = Tool.all
If you want it to be only accessible from one page, just declare it in the according method.
Here is an example, assuming you want to make the variable available for your home/index page:
class HomeController < ApplicationController
def index
#tools = Tool.all
respond_to do |format|
format.html # index.html.erb
end
end
end
If you want it to be accessible in all your pages, you can declare it in the before_filter method of your ApplicationController.
Here is how to do this:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :load_variables
# Load variables to be used everywhere
def load_variables
#tools = Tool.all
end
end
Im new to Ruby and rails. Im doing a form which updates :owner value in Hardware database. in using custom views name transfer.html.erb. my form code are display bellow.
<%= form_for #hardware, :url => do_transfer_path do |f| %>
this is my custom controller in hardwares_tranfers_controller.rb
def transfer
#hardware = Hardware.find(params[:id])
if current_user.user_lvl == 0
#users = User.order(:user_lvl)
else
#users = User.where(:refer => current_user.id)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #hardwares }
end
end
end
def do_transfer
# transfer_user = User.where(:id => #hardware.owner).email
# TransferLog.create([:user_id => current_user.id, :hardware_id => #hardware.id])
if #hardware.update_attributes(params[:hardware])
format.html { redirect_to users_url, notice: "Hardware was successfully transfer"}
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #hardware.errors, status: :unprocessable_entity }
end
end
and the error I get is
NoMethodError in HardwaresTransfersController#do_transfer
undefined method update_attributes' for nil:NilClass
Aplication Traces
app/controllers/hardwares_transfers_controller.rb:23:indo_transfer'
Parameter
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"vkwKyuS4eviRN1ogrpOcGh1Y5OBNX0wiBzpV8taNkq0=",
"hardware"=>{"owner"=>"3"},
"commit"=>"Transfer Hardware"}
my routes.rb
match "hardwares_transfers/" => "hardwares_transfers#do_transfer" , :as => :do_transfer
get "hardwares_transfers/:id/transfer" => "hardwares_transfers#transfer", :as => :transfer_hardwares
rake routes>
do_transfer /hardwares_transfers(.:format) hardwares_transfers#do_transfer
transfer_hardwares GET /hardwares_transfers/:id/transfer(.:format) hardwares_transfers#transfer
hardwares GET /hardwares(.:format) hardwares#index
POST /hardwares(.:format) hardwares#create
new_hardware GET /hardwares/new(.:format) hardwares#new
edit_hardware GET /hardwares/:id/edit(.:format) hardwares#edit
hardware GET /hardwares/:id(.:format) hardwares#show
PUT /hardwares/:id(.:format) hardwares#update
DELETE /hardwares/:id(.:format) hardwares#destroy
You need
def do_transfer
#hardware = Hardware.find(params[:id])
...
end
I'll also take this opportunity to point out that you could probably frame this in a more REST-ful manner
find hardware item:
def do_transfer
#hardware = Hardware.find(params[:id])
...
end
and change route.rb:
match "hardwares_transfers/:id" => "hardwares_transfers#do_transfer" , :as => :do_transfer
The error is NoMethodError in HardwaresTransfersController#do_transfer
undefined method update_attributes' for nil:NilClass.
As the error says, that Rails is trying to call update_attributes on nil:NilClass, which implies that your #hardware object is nil.
So, you should initialize it by
#hardware = Hardware.find(params[:id])
You should always look at the error and give it a thought as to why this error is there, it'll help you in learning better.