Ruby on Rails: Elastic Search Showing All the Posts - ruby-on-rails

I have added the elastic search gem and added a search button on the navbar however, when i want the user to search for posts it asks me to login or sign up. I want the user to be able to view the index page of the post and i added a before_filter in the posts_controller file but i don't know why it keeps asking me to sign up or log in. Here's my code:
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user! , except: [:index,:show]
before_filter :check_user, only: [:edit,:update,:destroy]
# GET /posts
# GET /posts.json
def search
if params[:search].present?
#posts = Post.search(params[:search])
else
#posts = Post.all
end
end
def index
if params[:tag]
#posts = Post.tagged_with(params[:tag])
else
#posts = Post.all
end
end
# GET /posts/1
# GET /posts/1.json
def show
#reviews = Review.where(post_id: #post.id)
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
#post.user_id = current_user.id
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to root_url, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
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, :description,:image,:all_tags)
end
def check_user
if current_user.id != #post.user_id
redirect_to root_path , alert: "Sorry this Post belongs to someone else"
end
end
end

You can use
skip_before_filter :authenticate_user! , :only => [:index,:show]
in your controller for skipping the before_filter for those actions.

I was able to solve the issue by adding the search method to the before_action post authentication. Here's the code:
before_action :authenticate_user! , except: [:index,:show,:search]

Related

[undefined local variable or method `current_user' in controller]

I've been around for this problem for 1 hour and not figuring out why it doesn't work.
I don't use gem devise.
I have user model, post model, UsersController.rb, PostsController.rb and 1 helper like below
PostsController.rb :
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = current_user.posts.build(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
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(:caption, :user_id)
end
end
ApplicationHelper.rb
module ApplicationHelper
def current_user
session[:user_id] && User.find(session[:user_id])
end
end
The current_user helper method works fine for all the views.
As I understand, PostsController inherits from ApplicationController, so it takes all the helpers from ApplicationHelper. I still dont figure out why this doesn't work.
Thanks for any help.
Try with adding this into ApplicationController.rb
helper_method :current_user

call helper methods in Rails 5 :
# sample :
module UsersHelper
def full_name(user)
user.first_name + user.last_name
end
end
class UsersController < ApplicationController
def update
#user = User.find params[:id]
if #user.update_attributes(user_params)
notice = "#{helpers.full_name(#user) is successfully updated}"
redirect_to user_path(#user), notice: notice
else
render :edit
end
end
end
Before Rails 5 :
# sample :
module UsersHelper
def full_name(user)
user.first_name + user.last_name
end
end
class UsersController < ApplicationController
include UsersHelper
def update
#user = User.find params[:id]
if #user.update_attributes(user_params)
redirect_to user_path(#user), notice: "#{full_name(#user) is successfully updated}"
else
render :edit
end
end
end

How to Add a Voting System to Nested Reviews in Ruby on Rails?

im trying to have a put a voting system (likes and dislikes) using the Ruby gem "act_as_votable" but i want to use that in my reviews model. keep in mind that the Reviews are nested inside the Post Model in my app. i tried to add that in my routes.rb file but its not working. does anyone know how to add a voting system for a nested model ? here's my code
Routes.rb
Rails.application.routes.draw do
devise_for :users
resources :posts do
resources :reviews , except: [:show,:index]
member do
get "like" , to: "reviews#upvote"
get "dislike" , to: "reviews#downvote"
end
end
get 'pages/help'
get 'pages/blog'
get 'pages/contact'
get 'pages/tour'
resources :posts
root 'posts#index'
end
reviewsController.rb
class ReviewsController < ApplicationController
before_action :set_review, only: [ :edit, :update, :destroy, :upvote,:downvote]
before_action :set_post
before_action :authenticate_user!
respond_to :html
def new
#review = Review.new
respond_with(#review)
end
def edit
#review = Review.find(params[:id])
#post = Post.find(params[:post_id])
end
def create
#review = Review.new(review_params)
#review.user_id = current_user.id
#review.post_id = #post.id
#review.save
redirect_to post_path(#post)
end
def update
#review.update(review_params)
respond_with(#review)
end
def destroy
#review.destroy
respond_with(#review)
end
def upvote
#review.upvote_bu current_user
redirect_to :back
end
def downvote
#review.downvote_bu current_user
redirect_to :back
end
private
def set_review
#review = Review.find(params[:id])
end
def set_post
unless #post = Post.where(id: params[:post_id]).first
redirect_to posts_path, flash: {alert: "Post doesn't exists"}
end
end
def review_params
params.require(:review).permit(:comment)
end
end
PostsController.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user! , only: [:edit,:update,:destroy,:new]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
#reviews = Review.where(post_id: #post.id)
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to root_path, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
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, :description)
end
end

NoMethodError Rails 3.2

I've been searching all over and can't find the answer to this anywhere.
I'm taking the intro to RoR course on udemy, and I've been able to solve all the problems I've had in the first 80% of the course, but now I'm at a roadblock and can't find this. We're building an app like Etsy, and I'm at the point where I need to restrict users from editing/deleting listings that don't belong to them.
I'm running Ruby 1.9.3 on Rails 3.2.21
I tried following the instructions for adding the check user filter, but when I checked back on local host, I received this error:
NoMethodError in ListingsController#edit
undefined method `user' for nil:NilClass
app/controllers/listings_controller.rb:98:in `check_user'
Parameters:
{"id"=>"8"}
My code matches the instructor's code exactly, but I think this error is because I'm using Rails 3, and he's using 4.
Here's my listings_controller.rb
class ListingsController < ApplicationController
# GET /listings
# GET /listings.json
before_filter :authenticate_user!, only: [:new, :create, :edit, :update, :destroy]
before_filter :check_user, only: [:edit, :update, :destroy]
def index
#listings = Listing.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #listings }
end
end
# GET /listings/1
# GET /listings/1.json
def show
#listing = Listing.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #listing }
end
end
# GET /listings/new
# GET /listings/new.json
def new
#listing = Listing.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #listing }
end
end
# GET /listings/1/edit
def edit
#listing = Listing.find(params[:id])
end
# POST /listings
# POST /listings.json
def create
#listing = Listing.new(params[:listing])
#listing.user_id = current_user.id
respond_to do |format|
if #listing.save
format.html { redirect_to #listing, notice: 'Listing was successfully created.' }
format.json { render json: #listing, status: :created, location: #listing }
else
format.html { render action: "new" }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# PUT /listings/1
# PUT /listings/1.json
def update
#listing = Listing.find(params[:id])
respond_to do |format|
if #listing.update_attributes(params[:listing])
format.html { redirect_to #listing, notice: 'Listing was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
#listing = Listing.find(params[:id])
#listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :no_content }
end
end
private
def set_listing
#listing = Listing.find(params[:id])
end
def listing_params
params.require(:listing).permit(:name, :description, :price, :image)
end
def check_user
if current_user != #listing.user
redirect_to root_url, alert: "Sorry, this listing belongs to someone else."
end
end
end
The code that we had to add for this is the second before_filter and the def check_user
If any other information is needed to help answer this, please let me know.
It's not a Rails 3 vs 4 issue, your code never calls set_listing and so #listing is never being set. You should probably have a:
before_filter :set_listing, only: [:show, :edit, :update, :destroy]
at the top of your file, before the before_filter :check_user, ...

generate slug url using rails 4

Based on this tutorial, I've created a slug url but when I click show or add post it showing error as :
ActiveRecord::RecordNotFound
Couldn't find Post with id=testing-seo-url
Instead of taking slug it is taking as id. where I have to make changes make this work.
Here is my controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render action: 'show', status: :created, location: #post }
else
format.html { render action: 'new' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
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, :content)
end
end
And here is my model:
class Post < ActiveRecord::Base
extend FriendlyId
friendly_id :title, use: :slugged
end
This is just a scaffold. I didn't create any other controller.
This solved
def set_post
#post = Post.friendly.find(params[:id])
end

Undefined method `title' for nil:NilClass in atom_feed

Disclaimer: I'm very new to Ruby on Rails.
Here is the error I am getting when attempting to generate a feed:
undefined method `title' for nil:NilClass
Extracted source (around line #2):
atom_feed do |feed|
feed.title "Who bought #{#product.title}"
feed.updated #latest_order.try(:updated_at)
Application trace:
app/views/products/who_bought.atom.builder:2:in `block in _app_views_products_who_bought_atom_builder__3166274680323093135_70240865825480'
app/views/products/who_bought.atom.builder:1:in `_app_views_products_who_bought_atom_builder__3166274680323093135_70240865825480'
This is my first time working with atom_feed - so I am really not sure what to look for here. What I have appears to be straight from the book "Agile Web Development with Rails 4" Am I missing something?
Should be:
CODING :
before_action :
set_product, only: [:show, :edit, :update, :destroy, :who_bought]
The problem was in a script I did not list - inside the products controller:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render action: 'show', status: :created, location: #product }
else
format.html { render action: 'new' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content }
end
end
def who_bought
#product = Product.find(params[:id])
#latest_order = #product.orders.order(:updated_at).last
if stale?(#latest_order)
respond_to do |format|
format.atom
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:title, :description, :image_url, :price)
end
end
The who_bought method, was listed under the private methods and I had also forgotten the '#' symbol in #latest_order
Your #product variable is nil. Did you defined it? Does the particular product exist?
Try to output it into console: logger.info #product.inspect

Resources