I'm trying to generate sitemap automatically by using a sitemap_generator gem. I tried to add show action since I started getting an error. It was originally empty..
Following is my posts controller:
class PostsController < ApplicationController
before_filter :authorize, only: [:edit, :update, :new, :create, :destroy]
before_filter :find_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.order("created_at DESC").page(params[:page]).per(9)
respond_to do |format|
format.html
format.rss { render :layout =>false }
end
end
def show
#posts = Post.all
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to posts_url
else
render 'new'
end
end
def edit
end
def update
if #post.update_attributes(post_params)
redirect_to post_url(#post), notice: "#{#post.title} Updated"
else
render 'edit'
end
end
def destroy
#post.destroy
redirect_to posts_url, notice: "#{#post.title} Deleted"
end
private
def post_params
params.require(:post).permit(:title, :contents, :author_id, :approved, :summary, :preview_image_id, :category, :social_title, :blog_title)
end
def find_post
#post = Post.friendly.find(params[:id])
# If an old id or a numeric id was used to find the record, then
# the request path will not match the post_path, and we should do
# a 301 redirect that uses the current friendly id.
if params[:action] == 'show' && request.path != post_path(#post)
return redirect_to #post, :status => :moved_permanently
end
end
end
routes.rb
Rails.application.routes.draw do
root to: "home#index"
resources :posts do
resources :comments
end
end
sitemap.rb
Post.friendly.find_each do |post|
add post_url(post), :lastmod => post.created_at
end
I tried both with 'friendly' and without 'friendly'.
and When I run rake sitemap:refresh I receive the following error
ubuntu:~/environment/site (master) $ rake sitemap:refresh
In '/home/ubuntu/environment/site/public/':
Post Load (0.6ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT 1000
rake aborted!
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"posts", :format=>nil, :id=>nil, :locale=>#<Post id: 1, title: "4 Tips For Managing Your Maintenance Team", contents: "<p>Maintenance teams are a special kind of problem...", approved: nil, created_at: "2020-03-30 16:17:28", updated_at: "2020-05-04 17:07:30", url: nil, blog_title: "4 Tips For Managing Your Maintenance Team">} missing required keys: [:id]
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'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.
I'm a beginner to Ruby on Rails working on a Notebook app. I'm trying using Searchkick to enable users to quickly search their notes. I currently have 2 users (via devise gem).
I have just set up Searchkick, but when I search for a word that both the users have in their notes, the result shows notes by both users. So, a user can see the other's note in this case as in the image below.
Here is my notes_controller.rb code:
class NotesController < ApplicationController
before_action :find_note, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#notes = Note.where(user_id: current_user).order("created_at DESC")
end
def search
if params[:search].present?
#notes = Note.search(params[:search])
else
#notes = Note.all
end
end
def new
#note = current_user.notes.build
end
def create
#note = current_user.notes.build(note_params)
if #note.save
redirect_to root_path, notice: "Note successfully created."
else
render 'new'
end
end
def show
end
def edit
end
def update
if #note.update(note_params)
redirect_to note_path(#note), notice: "Note successfully updated."
else
render 'edit'
end
end
def destroy
#note.destroy
redirect_to root_path, notice: "Note successfully deleted."
end
private
def note_params
params.require(:note).permit(:title, :body)
end
def find_note
#note = Note.find(params[:id])
end
end
My routes.rb code:
Rails.application.routes.draw do
devise_for :users
resources :notes do
collection do
get :search
end
end
authenticated :user do
root "notes#index"
end
root "welcome#home"
end
My search.html.erb code, which is the same as index.html.erb code:
<% #notes.each do |note| %>
<h2><%= link_to note.title, note_path(note) %></h2>
<% end %>
I have a feeling I need to add a conditional statement in the search action in the notes_controller but that is not working.
Can anyone help please?
Thank you.
That would be
#notes = Note.search params[:search], where: { user_id: current_user.id }
I'm currently creating a website that would allow a visitor to read a magazine online. I created a scaffold for the magazine itself, and another one for the pages, which belongs to the magazine. This way, I can create a multi upload for the pages while creating the magazine, and everything gets uploaded in the same time.
When I nest the pages resources inside the magazine's resources, as following:
resources :magazines do
resources :pages
end
I get "domain.com/magazines/<slug>/pages/id"
However, I had some issues with the id, because it can't be used to count the pages (since the id never goes back to 1), so I created a function inside the controller that would count the pages for me, and save each pages with a "page_number" value.
My question is the following: how, instead of the id, can I kindly ask my router to use the :page_number ?
I tried to create a custom route, which looked like this
resources :magazines do
get '/:page_number' => 'pages#show', as: :custom_page
end
But for an unknown reason, Rails tells me that my custom route simply doesn't exist, even though it exists when I type rake routes
Thank you in advance
Edit
Here is my magazine_controller.rb
class MagazinesController < ApplicationController
before_action :authenticate_user!, only: [:edit, :update, :destroy]
before_action :set_magazine, only: [:show, :edit, :update, :destroy]
def index
#magazines = Magazine.all
end
def show
end
def new
#magazine = Magazine.new
end
def edit
end
def create
#magazine = Magazine.new(magazine_params)
if #magazine.save
if params[:images]
(params[:image] || []).each_with_index do |image, index|
#magazine.pages.create(image: image, page_number: index + 1)
end
redirect_to #magazine, notice: 'Magazine was successfully created.'
else
render :new
end
end
end
def update
if #magazine.update(magazine_params)
if params[:images]
params[:images].each { |image|
#magazine.pages.create(image: image)
}
end
redirect_to #magazine, notice: 'Magazine was successfully updated.'
else
render :edit
end
end
def destroy
#magazine.destroy
redirect_to magazines_url, notice: 'Magazine was successfully destroyed.'
end
private
def set_magazine
#magazine = Magazine.friendly.find(params[:id])
end
def magazine_params
params.require(:magazine).permit(:titre, :apercu)
end
end
and here is page_controller.rb
class PagesController < ApplicationController
before_action :authenticate_user!, only: [:edit, :update, :destroy]
before_action :set_page, only: [:show, :edit, :update, :destroy]
def index
#pages = Page.all
end
def show
end
def new
#page = Page.new
end
def edit
end
def create
#page = Page.new(page_params)
if #page.save
redirect_to #page, notice: 'Page was successfully created.'
else
render :new
end
end
def update
if #page.update(page_params)
redirect_to #page, notice: 'Page was successfully updated.'
else
render :edit
end
end
def destroy
#page.destroy
redirect_to :back, notice: 'Page was successfully destroyed.'
end
private
def set_page
#page = Page.find(params[:id])
end
def page_params
params.require(:page).permit(:titre, :apercu)
end
end
Edit 2
Here is the output from development.log when trying to reach the page
Started GET "/magazines/magazine-54/pages/11" for 127.0.0.1 at 2016-12-12 11:04:45 +0100
Processing by PagesController#show as HTML
Parameters: {"magazine_id"=>"magazine-54", "id"=>"11"}
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `pages' for nil:NilClass):
app/controllers/pages_controller.rb:49:in `set_page'
Rendering /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (2.4ms)
Rendering /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.2ms)
Rendering /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.7ms)
Rendered /var/lib/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (13.8ms)
With these routes
resources :magazines do
resources :pages
end
you should be able to update PagesController and add/update following methods:
def magazine
#magazine = Magazine.find(params[:magazine_id])
end
def page
#page = #magazine.pages.find_by(page_number: params[:id])
end
to make it work you should have page_number column in Page model and has_many :pages association in Magazine model
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| %>