I'm getting this error message (Couldn't find Portfolio with 'id'=edit) when I try to edit my show page.
def set_portfolio_item
#portfolio_item = Portfolio.find(params[:id])
end
I've tried editing the id by putting edit there but it still doesn't work
class PortfoliosController < ApplicationController
skip_before_action :verify_authenticity_token
before_action :set_portfolio_item, only: [:edit, :show, :update, :destroy]
layout 'portfolios'
access all: [:show, :index, :angular], user: {except: [:destroy, :new, :create, :update, :edit, :sort]},site_admin: :all
def index
#portfolio_items = Portfolio.by_position
#page_title = "Portfolios"
end
def sort
params[:order].each do |key, value|
Portfolio.find(value[:id]).update(position: value[:position])
end
render json: { status: "updated" }
end
def new
#portfolio_item = Portfolio.new
3.times { #portfolio_item.technologies.build }
end
def create
#portfolio_item = Portfolio.new(portfolio_params)
respond_to do |format|
if #portfolio_item.save
format.html { redirect_to portfolios_path, notice: 'Your portfolio item is now live.'}
else
format.html { render :new }
end
end
end
def edit
end
def update
respond_to do |format|
if #portfolio_item.update(portfolio_params)
format.html { redirect_to portfolios_path, notice: 'The record successfully updated.' }
else
format.html { render :edit }
end
end
end
def show
end
def destroy
#this going to perform the look up
# Destroy/delete the record
#portfolio_item.destroy
# Redirect
respond_to do |format|
format.html { redirect_to portfolios_url, notice: 'Post was removed.' }
end
end
private
def portfolio_params
params.require(:portfolio).permit(
:title,
:subtitle,
:body,
:main_image,
:thumb_image,
technologies_attributes: [:name]
)
end
def set_portfolio_item
#portfolio_item = Portfolio.find(params[:id])
end
end
when clicking on http://localhost:3000/portfolios/edit, I expected to go to the show edit page, but getting
ActiveRecord::RecordNotFound in PortfoliosController#show
Couldn't find Portfolio with 'id'=edit
this is my routes for show
portfolios_show GET /portfolios/:id(.:format) portfolios#show
blog GET /blogs/:id(.:format) blogs#show
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format)
active_storage/disk#show
this is my route for edit
edit_user_password GET /password/edit(.:format) devise/passwords#edit
edit_user_registration GET /edit(.:format) devise/registrations#edit
edit_portfolio GET /portfolios/:id/edit(.:format) portfolios#edit
edit_blog GET /blogs/:id/edit(.:format) blogs#edit
When I click on http://localhost:3000/portfolios/edit, I can error message
ActiveRecord::RecordNotFound in PortfoliosController#show Couldn't find Portfolio with 'id'=edit
If you want to edit a portfolio, you must supply an id, like so http://localhost:3000/portfolios/1/edit. Your current URL can only be interpreted as portfolios#show, with "edit" being the :id part of the route.
Related
Basically, I'm trying to update the layout of my portfolio/new form but whenever I type in 'localhost:3000/portfolios/new' I get redirected to my home page. Same with 'localhost:3000/portfolios/(:id)/edit'
My routes are below:
Rails.application.routes.draw do
#Devise Routes
devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout', sign_up: 'register' }
#homepages routes
get 'about-me', to: 'pages#about'
get 'contact', to: 'pages#contact'
# blog
resources :blogs do
member do
get :toggle_status
end
end
#portfolio
resources :portfolios, except: [:show]
get 'portfolio/:id', to: 'portfolios#show', as: 'portfolio_show'
get 'react-items', to: 'portfolios#react'
# setting root path --> ex: localhost:3000/
root to: 'pages#home'
end
Here is my controller:
class PortfoliosController < ApplicationController
before_action :set_portfolio_item, only: [:edit, :update, :show, :destroy]
layout "portfolio"
access all: [:show, :index, :react], user: {except: [:destroy, :new, :create, :update, :edit]}, site_admin: :all
def index
#portfolio_items = Portfolio.all
end
# custom scope
def react
#react_portfolio_items = Portfolio.react
end
def show
end
def new
# new portfolio item is initialized.
#portfolio_item = Portfolio.new
3.times { #portfolio_item.technologies.build }
end
def create
#portfolio_item = Portfolio.new(portfolio_params)
respond_to do |format|
if #portfolio_item.save
format.html { redirect_to portfolios_path, notice: 'Portfolio Item was successfully created.' }
else
format.html { render :new }
end
end
end
def edit
end
def update
respond_to do |format|
if #portfolio_item.update(portfolio_params)
format.html { redirect_to portfolios_path, notice: 'Portfolio Item was successfully updated.' }
else
format.html { render :edit}
end
end
end
def destroy
# destroy the record
#portfolio_item.destroy
# redirect
respond_to do |format|
format.html { redirect_to portfolios_url, notice: 'Record was removed.' }
end
end
private
def portfolio_params
params.require(:portfolio).permit(:title,
:subtitle,
:body,
technologies_attributes: [:name]
)
end
def set_portfolio_item
#portfolio_item = Portfolio.find(params[:id])
end
end
So overall I'm not sure why it's doing that. When I do rails routes I can see the correct paths but when I input them in the browser, they do not work.
Any help would be greatly appreciated.
I think you had reverted access to create/update/edit/destroy.
Remove except condition from access_all for user create/update/edit/destroy
when user trying to opening a page which doesn't has permission to view, it will be redirect_to its root_path by default.
I have a model named Group which has_many Posts and each Post has_many Comments. I can navigate to a group, create a post and then create a comment under that post. My issue is when I try and delete a comment I receive the below error about the redirect (the comment is deleted the redirect just doesn't happen).
undefined method `id' for nil:NilClass
this is the line in my destry action it does not like, which is weird because my update action has the same redirect and that works fine.
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully destroyed.' }
I tried adding [:destroy] onto the set_post before_action thinking that it might need that but no luck.
here's some of my routes
group_posts GET /groups/:group_id/posts(.:format) posts#index
POST /groups/:group_id/posts(.:format) posts#create
new_group_post GET /groups/:group_id/posts/new(.:format) posts#new
edit_group_post GET /groups/:group_id/posts/:id/edit(.:format) posts#edit
group_post GET /groups/:group_id/posts/:id(.:format) posts#show
PATCH /groups/:group_id/posts/:id(.:format) posts#update
PUT /groups/:group_id/posts/:id(.:format) posts#update
DELETE /groups/:group_id/posts/:id(.:format) posts#destroy
groups GET /groups(.:format) groups#index
POST /groups(.:format) groups#create
here's my comments_controller.rb
class CommentsController < ApplicationController
before_action :set_group, only: [:index, :show, :new, :edit, :create, :update]
before_action :set_post, only: [:index, :show, :new, :edit, :create, :update]
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /posts/:post_id/comments
def index
#comments = #post.comments.order(created_at: :desc)
end
def show
end
# GET /posts/:post_id/comments/new
def new
#comment = #post.comments.new
end
# # GET /posts/:post_id/comments/edit
# def edit
# end
# POST /posts/:post_id/comments
def create
# inserts current_user into the comments foriegn key for user_id.
#comment = #post.comments.new(comment_params.merge(user_id: current_user.id))
respond_to do |format|
if #comment.save
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully created.' }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/:post_id/comments/:id
def update
respond_to do |format|
if #post.comments.update(comment_params)
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully updated.' }
format.json { render :show, status: :ok, location: #comment }
else
format.html { render :edit }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/:post_id/comments/:id
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
###################
# private methods
###################
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
def set_post
#post = Post.find(params[:post_id])
end
def set_group
#group = Group.find(params[:group_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:content, :post_id, :user_id)
end
end
If you'd like to reference the #group instance variable, you should add :destroy to the before_action set_group callback:
before_action :set_group, only: [:index, :show, :new, :edit, :create, :update, :destroy]
You should also add :destroy to the before_action set_post callback as well
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
I'm having issues with routing a rails app to use a new and edit form.
The routes use the username within the URL.
lists GET /lists(.:format) lists#index
POST /user/:username/lists(.:format) lists#create
new_list GET /user/:username/lists/new(.:format) lists#new
edit_list GET /user/:username/lists/:id/edit(.:format) lists#edit
list GET /user/:username/lists/:id(.:format) lists#show
PATCH /user/:username/lists/:id(.:format) lists#update
PUT /user/:username/lists/:id(.:format) lists#update
DELETE /user/:username/lists/:id(.:format) lists#destroy
root GET / static#welcome
show_user GET /user/:id(.:format) users#show
My routes.rb-
get 'lists', to: 'lists#index', as: :lists, via: 'get'
scope 'user/:username' do
resources :lists, except: [:index]
end
My shared form, for use with updating and creating-
<%= form_for [#user, #list], url: list_path(#user, #list) do |f| %>
Using the above settings, I can edit lists correctly, but if I navigate to lists#new, I get the following error-
No route matches {:action=>"show", :controller=>"lists", :id=>nil, :username=>"test"} missing required keys: [:id]
If I pluralize the path in my form to be url: lists_path(#user, #list), then the new page will now load, but when trying to create I get the below error-
No route matches [POST] "/lists.test"
How can I fix these routes so I can use the same shared form for both edits and creating?
Adding controller code-
class ListsController < ApplicationController
before_action :set_list, only: [:show, :edit, :update, :destroy]
def index
#lists = List.all
end
def show
end
# GET /lists/new
def new
#list = List.new
#user = User.find_by(username: params[:username])
end
def edit
#user = User.find_by(username: params[:username])
end
def create
#list = current_user.lists.new(list_params)
respond_to do |format|
if #list.save
format.html { redirect_to list_path(#list.user.username, #list.id), notice: 'List was successfully created.' }
else
format.html { render :new }
end
end
end
def update
respond_to do |format|
if #list.update(list_params)
format.html { redirect_to list_path(#list.user.username, #list.id), notice: 'List was successfully updated.' }
else
format.html { render :edit }
end
end
end
def destroy
#list.destroy
respond_to do |format|
format.html { redirect_to lists_url, notice: 'List was successfully destroyed.' }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_list
#list = List.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def list_params
params.require(:list).permit(:name, :category, :user_id)
end
end
Try this - Change the :url value in the form_for to [[#list], :username => #user.username]
Like so:
<%= form_for [#user, #list], url: [[#list], :username => #user.username] do |f| %>
I have two models post and topic in my rails app
class Post < ActiveRecord::Base
#relation between topics and post
belongs_to :topic
#post is valid only if it's associated with a topic:
validates :topic_id, :presence => true
#can also require that the referenced topic itself be valid
#in order for the post to be valid:
validates_associated :topic
end
And
class Topic < ActiveRecord::Base
#relation between topics and post
has_many :posts
end
I am trying to create association between both of them.
I want multiple post corresponding to each topic
I have used nested routes
Rails.application.routes.draw do
# nested routes
resources :topics do
resources :posts
end
resources :userdetails
devise_for :users, :controllers => { :registrations => "registrations" }
My Post controller looks like
class PostsController < ApplicationController
# before_action :set_post, only: [:show, :edit, :update, :destroy]
before_filter :has_userdetail_and_topic, :only =>[:new, :create]
# GET /posts
# GET /posts.json
#for new association SAAS book
protected
def has_userdetail_and_topic
unless(#topic =Topic.find_by_id(params[:topic_id]))
flash[:warning] = 'post must be for an existing topic'
end
end
public
def new
#post = #topic.posts.build
###topic = Topic.find(params[:topic_id1])
end
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
##topic.posts << #post
##current_user = current_user.id
#current_user.posts << #topic.posts.build(params[:post])
##post = Post.new(post_params )
##post.userdetail_id = current_user.id
#Association functional between topic and post
#Class variable used
###topic.posts << #post
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(:topic_id,:issue, :description, :rating, :userdetail_id)
end
end
I am trying to navigate from topics/index via code <td><%= link_to 'Write', new_topic_post_path(#topic) %> </td>
but when i try to go at localhost:3000/topics]
I am getting error
No route matches {:action=>"new", :controller=>"posts", :topic_id=>nil} missing required keys: [:topic_id]
Can any body tell me about this error, as i am new to rails please clearly specify answer.
And I have one more doubt, please tell me if i am doing association between topic and post incorrectly.I have confusion about this line of code -
#topic.posts << #post
What the error missing required keys: [:topic_id] is telling you is that you need to provide a hash with the key topic_id:
<%= link_to 'Write', new_topic_post_path(topic_id: #topic) %>
Passing a resource as to a route helper only works for the id param:
<%= link_to #topic, topic_path(#topic) %>
Is a kind of shorthand for:
<%= link_to #topic, topic_path(id: #topic.to_param) %>
Addition:
#prcu is also correct. The #topic record needs to be saved to the database. Records which are not saved do not have an id since the database assigns the id column when the record is inserted.
You also need to set the #topic instance variable in PostsController:
#topic = Topic.find(params[:id])
This is commonly done with a before filter:
before_filter :set_topic, only: [:new]
def set_topic
#topic = Topic.find(params[:id])
end
The same also need to be done in TopicsController#index.
#topic is not set or it's not persisted. You can not use topic not saved to db in this helper.