undefined method `each' for nil:NilClass error for index - ruby-on-rails

I created a seed which I made sure worked by testing it in the rails console beforehand. Now I am trying show the instance variable #services in my view, but I have an error that says it's nill.
Any ideas?
Thank you
//home.html.erb
<div>
<% #services.each do |service| %>
<%= service.name %>
<% end %>
</div>
//services_controller.rb
class ServicesController < ApplicationController
before_action :set_service, only: [:index, :show]
def index
#services = Service.all
end
def show
set_service
end
private
def set_service
#service = Service.find(params[:id])
end
end
//service.rb
class Service < ApplicationRecord
validates :name, presence: true
validates :description, presence: true
has_many :reviews
end
This is the error that's being rendered
undefined method `each' for nil:NilClass

add root URL mapping, and point it to services index action, as in root 'services#index' in config/routes.rb
move content of home.html.erb to views/services/index.html.erb
change before_action :set_service, only: [:index, :show] to before_action :set_service, only: :show
See the comments on question :)

Change this code:
before_action :set_service, only: [:index, :show]
To this:
before_action :set_service, only: [:show]

Related

NoMethodError (undefined method `posts' for nil:NilClass):

Somebody help me pleases, I sent local server post method but happened as the above error so i tried a lot of things recreate table, changed path and model name and so on
However I couldn't slove it , I want to know how to fix it and why happed this error,
Ruby 2.5.3 Rails 6.0.0 rc2
Controller
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:new]
def index
#posts = current_user.posts.all
end
def new
#post = Post.new
end
# Maybe here is happening error
def create
if #post = current_user.posts.build(posts_params)
flash[:success] = "You created post"
redirect_to #posts
else
flash[:failed] = "You failed posted "
end
end
def edit
end
def show
end
private
def posts_params
params.require(:posts).permit(:title , :content , :user_id)
end
end
Routes
Rails.application.routes.draw do
devise_for :users , :paths => 'users'
resources :users do
resources :posts , :except => :edit
end
root 'users#index'
end
User model
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:authentication_keys => [:name]
validates :name, presence: true, uniqueness: true , length:{maximum: 10}
has_many :posts
Thanks everyone, It seems to be problem is current_user
So, I use byebug so that (byebug) current_user
User Load (0.5ms) SELECT users.* FROM users WHERE users.id = 1 ORDER BY users.id ASC LIMIT 1
↳ (byebug):1:in `create'
Again thanks everyone, I rewrote code
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:index, :new, :create]
def index
#posts = current_user.posts.all
end
def new
#post = Post.new
end
def create
if #post = current_user.posts.create(posts_params)
flash[:success] = "You created post"
redirect_to user_posts_path
else
flash[:failed] = "You failed posted "
end
end
def edit
end
def show
end
private
def posts_params
params.require(:posts).permit(:title , :content , :user_id)
end
end
Sadly this code also doesn't work , just in case , i wrote form code
<%= form_with model: #post , url: user_posts_path ,local: true do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :content %>
<%= f.text_area :content %>
<% f.label :user_id %>
<% f.hidden_field :user_id %>
<%= f.submit "Create Post" %>
In your Controller, you only require user to login for action new. This causes every other page user can visit / interact without authentication.
So, with your controller code, you will get the error undefined posts for nil if there's no logged in user with this call current_user.posts
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:new]
def index
#posts = current_user.posts.all
end
def new
end
def create
if #post = current_user.posts.build(posts_params)
# ...
end
end
def edit
end
def show
end
end
To fix this error, you can add more actions requiring user authentication
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:index, :new, :create]
end
or just require it for all actions of the controller
class PostsController < ApplicationController
before_action :authenticate_user!
end
There are several errors in the code:
Check user for create action
before_action :authenticate_user!, only: %i[new create]
Use create method instead of build method and fix redirect problem.
def create
if #post = current_user.posts.create(posts_params)
flash[:success] = "You created post"
redirect_to #post
else
flash[:failed] = "You failed posted"
end
end
However, if you get an error, check the devise configuration for current_user.
Change from
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:new]
end
to
class PostsController < ApplicationController
before_action :authenticate_user!
end
Because you call current_user in index action, and basically I think all the actions requires user to log in.

rails nested resources no route matches missing required key [:id]

I have a very simple case of nested resources but I am having trouble to get them to work.
My models:
class TodoList < ActiveRecord::Base
has_many :todo_items, dependent: :destroy
class TodoItem < ActiveRecord::Base
belongs_to :todo_list
My controller:
class TodoItemsController < ApplicationController
before_action :set_todo_list
before_action :set_todo_item, only: [:show, :edit, :update, :destroy]
def show
end
private
def set_todo_item
#todo_item = #todo_list.todo_items.find(params[:id])
end
def set_todo_list
#todo_list = TodoList.find(params[:todo_list_id])
end
My show.html.erb:
<%= link_to 'Edit', edit_todo_list_todo_item_path([#todo_item.todo_list, #todo_item]) %>
I got the error
"No route matches {:action=>"edit", :controller=>"todo_items", :id=>nil, ..., missing required keys: [:id].
I know the todo_item_id is missing, but I couldn't figure out why. When I debug, I saw that both #todo_list and #todo_item were getting values. But as soon as the #todo_item was assigned, this error would rise. What did I do wrong? How can I correct this? Any insights will be appreciated.
Try this:
<%= link_to 'Edit', edit_todo_list_todo_item_path(#todo_item.todo_list, #todo_item) %>
or:
<%= link_to 'Edit', edit_todo_list_todo_item_path(todo_list_id: #todo_item.todo_list.id, id: #todo_item.id) %>

undefined local variable or method `product' for #<#<Class:0x007fe77c4f3c68>:0x007fe77c69cb78>

I´m having a problem with an app that I´m building.
in products/show.html.erb I have this code to add product to cart.
<%= button_to product_items_path(product_id: product) do %>
<i class="fa fa-shopping-cart"></i>Add to Cart
<% end %>
And it always gives me this error undefined local variable or method 'product' for #<#<Class:0x007fe77c4f3c68>:0x007fe77c69cb78>
This error is happening in the first line According to Better Error gem
I'am using ActiveAdmin but I'm pretty sure that the error is not appearing because of that.
I'm not sure why this is happening, to me the code seems good but I must be overseeing something.
It would be great if someone could take look and maybe see what I´m not seeing.
This is the `ProductItemsController.rb``
class ProductItemsController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:create]
before_action :set_product_item, only: [:show, :destroy]
def create
product = Product.find(params[:product_id])
#product_item = #cart.add_product(product.id)
if #product_item.save
redirect_to root_url, notice:'Product added to Cart'
else
render :new
end
end
private
def set_product_items
#product_item = ProductItem.find(params[:id])
end
def product_item_params
params.require(:product_item).permit(:product_id)
end
end
And here is the ProductsController.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
def show
end
private
def set_product
#product = Product.find(params[:id])
end
def product_params
params.require(:product).permit(:name, :description, :price_usd, :price_isl, :image, :category_id)
end
end
this is the routes.rbfile
Rails.application.routes.draw do
resources :categories
resources :labels
resources :products
resources :carts
resources :product_items
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
root 'pages#index'
Only instance variables are available to the view.
def create
#product = Product.find(params[:product_id]) # Prefix variable name with #
#product_item = #cart.add_product(product.id)
if #product_item.save
redirect_to root_url, notice:'Product added to Cart'
else
render :new
end
end
And your view:
<%= button_to product_items_path(#product) do %>
<i class="fa fa-shopping-cart"></i>Add to Cart
<% end %>
You should be able to just pass in the object to the _path helper.

Concatenate two fiels into one for Rails

I want to concatenate two fiels (address and place) into 1 field (location).
I have created the following code in my pins controller:
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy, :like, :unlike]
before_action :authenticate_user!, except: [:index, :show]
before_action :correct_user, only: [:destroy]
before_save :set_location
def set_location
location = "#{address} #{place}"
end
...
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
#pin = Pin.find(params[:id])
end
def correct_user
#pin = current_user.pins.find_by(id: params[:id])
redirect_to pins_path, notice: "It is only allowed to change the restaurants you have added my yourself." if #pin.nil?
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description, :image, :name, :address, :place, :postal_code, :telephone_number, :website, :emailadress, :location)
end
end
I get this error message
undefined method `before_save' for PinsController:Class
Does anyone knows what I am doing wrong?
before_save is callback for Models, not for Controllers.
You should do:
class Pin < ActiveRecord::Base
before_save :set_location
def set_location
self.location = "#{self.address} #{self.place}"
end
end
You are using the before_save hook in your controller instead of the model.
Move this code to your model and it should work.
class Pin < ActiveRecord::Base
before_save :set_location
# ...
def set_location
self.location = "#{address} #{place}"
end
end

Creating a new link_to for a nested resource

I'm trying to use the link_to helper function to create a new order for a particular product. Here is my:
product model
class Product < ActiveRecord::Base
has_many :orders
end
routes.rb
resources :products, :only => [:show, :new, :create, :index, :update, :destroy] do
resources :orders, :only => [:create]
end
view for product/show.html.erb
<%= link_to 'New Order', new_product_orders_path(#product) %>
controller for orders
class OrdersController < ApplicationController
def create
#order = Order.new
end
end
relevant rake routes:
product_orders POST /products/:product_id/orders(.:format) orders#create
But when I do that I get undefined method `new_product_orders_path'
Whats the correct way to do this in Rails 4?
In your routes add new action here
resources :orders, :only => [:create, :new]
Also your controller is missing new action, in your create action you need to save your record
class OrdersController < ApplicationController
before_filter :set_product
def new
#order = #product.orders.new
end
def create
#order = #product.orders.new(params[:order])
#order.save
end
private
def set_product
#product = Product.where("id =?", params[:product_id]).first
end
end
I think you need
resources :products, :only => [:show, :new, :create, :index, :update, :destroy] do
resources :orders, :only => [:create, :new]
end
You can also check your routes by typing '/rails/info/routes' at the end of your server path.

Resources