please help solve the problem.
a resource documents and the appropriate controller:
class DocumentsController < ApplicationController
def index
#documents = Document.all.paginate(page: params[:page], per_page: 10)
end
def admin_index
#documents = Document.all.paginate(page: params[:page], per_page: 10)
render layout: "admin"
end
def show
#document = Document.find(params[:id])
end
def admin_show
#document = Document.find(params[:id])
render layout: "admin"
end
....
....
end
a 2 layouts:
application.html.erb,
admin.html.erb
the controller index lists the documents in the public section (application.html.erb).
admin_index controller displays a list of documents in the closed part of the site (admin.html.erb).
in the public part of the site I can look any document by clicking on 'show':
<% #documents.each do |document| %>
<%= document.title %>
<%= link_to 'Show', document %>
<% end %>
The problem is that in a closed part of the site I did not get to see any document by clicking the link below:
<%= link_to 'Show', document %>
a problem that throws me a page of a particular document, but the layout: application.html.erb, and I need a layout: admin.html.erb
routes:
Testpager::Application.routes.draw do
get "admin/index"
resources :news, only: [:index, :show]
resources :documents, only: [:index, :show, :destroy]
get "contacts/index"
get "services/index"
get "index/index"
get "admin/index"
get "admin/documents" => 'documents#admin_index'
get "admin/documents/:id" => 'documents#admin_show'
root 'index#index'
end
First of all, there's no difference in the link you've created with the link_to helper in your index.html.erb and admin_index.html.erb, so let's address that first.
Change your admin_show route in your routes.rb to:
get 'admin/documents/:id', to: 'documents#admin_show', as: 'admin_document'
Now change the link_to in your admin_index.html.erb to this:
<%= link_to 'Show', admin_document_path(document) %>
That should do it.
Side note
The way you've set up the 'public' and 'admin' parts of your site seem odd. I would personally create an admin namespace and a separate DocumentsController in that namespace. You'll have to change your routes.rb, create an admin controller, view and layout if you want this.
Add the documents resource to the admin namespace instead of the admin routes you've already added:
...
namespace :admin do
resources :documents, only: [:index, :show, :destroy]
end
resources :documents, only: [:index, :show, :destroy]
...
Create a app/controllers/admin/documents_controller.rb file and move the admin_* methods from your original controller to that one and also move the admin_*.html.erb views to app/views/admin/*.html.erb.
Now, last but not least move your app/views/layouts/admin.html.erb file to app/views/layouts/admin/application.html.erb. That should do it.
Note that you've got to use a module in your admin controller:
module Admin
class DocumentsController < ApplicationController
...
end
end
Related
I have an application entity called Source on my app. This entity has a property called url.
I want to make a processing on my SHOW view. So I added a button on the show view to make a call to my controller and do this processing.
This is my routes.rb
get '/process', to: 'sources#read', as: 'read'
This is my controller method:
class SourcesController < ApplicationController
before_action :set_source, only: [:show, :edit, :update, :destroy, :read]
access all: [:index, :show, :new, :edit, :create, :update, :destroy, :read], user: :all
def read
require 'rss'
require 'open-uri'
url = #source.url
open(url) do |rss|
feed = RSS::Parser.parse(rss)
puts "Title: #{feed.channel.title}"
feed.items.each do |item|
puts "Item: #{item.title}"
puts "Link: #{item.link}"
puts "Description: #{item.description}"
end
end
render template: 'rss_reader/home'
end
And of course. My show.html.erb:
<%= button_to 'Process Source', read_path(#source), method: :get %>
<%= link_to 'Edit', edit_source_path(#source) %> |
<%= link_to 'Back', sources_path %>
</div>
When I press the "Process Source" button, it goes to the right controller method, but the object #source its not being found because of:
Couldn't find Source with 'id'=
# Use callbacks to share common setup or constraints between actions.
def set_source
#source = Source.find(params[:id])
end
What Im doing wrong here?
You are visiting the route with read_path(#source) which is expected to set the param id to the value #source.id, but you did not define your routes to support any parameter in the path.
I believe read is an action that belongs to a single instance of Source. So, you should define the route on member. This way you will be able to access params[:id] in your controller and your before_action set_source will work fine.
Change your route definition to:
resources :sources, only: [...] do # Keep the `only` array just as you have now.
get '/process', to: 'sources#read', as: 'read', on: :member
end
I have previewed all questions with similar topics and none of those solutions help me. I am attempting to create a twitter like feed that will display posts of a certain category in rails.
This is my industries controller:
class IndustriesController < ApplicationController
def index
#wads = Wad.order('created_at DESC')
end
def music
#music_wads = Wad.where(category: "Music").paginate(page: params[:page], per_page: 20)
#wad = #music_wads.pluck(:id)
end
end
This is part of my posts controller:
class WadsController < ApplicationController
before_action :find_wad, only: [:show, :edit, :update, :destroy]
def index
#wads = Wad.all
end
def show
#wad = Wad.find(params[:id])
end
def new
#wad = Wad.new
end
def create
#wad = current_user.wads.build(wad_params)
if #wad.save
redirect_to #wad
else
flash[:error] = 'Error try again'
render 'new'
end
end
end
And this is my show view for my industries controller:
<h1>Music Wads</h1>
<%= will_paginate #music_wads %>
<% #music_wads.each do |music_wad| %>
<%= link_to 'wads/:id' do %>
<div class="flex-rectangle">
<%= music_wad.user.name %>
<%= music_wad.short_form %>
<% end %>
</div>
<%= will_paginate #music_wads %>
<% end %>
Here is my routes file:
Rails.application.routes.draw do
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
get '/industries', to: 'industries#index'
get '/music', to: 'industries#music'
get '/tech', to: 'industries#tech'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :wads
end
I am attempting to make it so that clicking on a post among the lists of post carries you to page of that post (/wads/id). I've been baffled all day and am now at my wits end. I am aware I am a noob and this is a nooby question but any help would gladly be appreciated.
Thanks
resources :wads will create some routes that you can use.
Running rails routes (on rails 5) or rake routes (on rails 4 and lower) in the console will give you the list of your routes.
Under the prefix column you could find the correct route name you should use and under the URI Pattern you could see the actual address it links to.
You asked for wads/:id so the link should be <%= link_to wad_path(wad_music) do %> (the prefix is wad_path and you need to give it the object which holds the id - or an id...)
Since you want to link to a singular action - meaning that the action will get and id of an object - and get it (gets a single object!) the link prefix will be in singular form as well: wad_path and not wads_path
(wads_path will link to the index action in the controller and doesn't need to get any object or id)
I know this has been asked but no solution has worked.
I'm trying to pass a group id to a procedure controller so I may make that procedure belong to that group.
Group Show View:
<%= link_to 'Create a Procedure', new_procedure_path(:group => #group.id), class: 'btn btn-default btn-small' %>
Procedure controller:
def new
#procedure = Procedure.new
#group = Group.find(params[:group])
Routes :
resources :groups, only: [:new, :create, :show, :destroy]
resources :procedures
If group_id is required, make it part of the url and won't need it in the form view. You'll have group_id in the params: params[:group_id] is what the controller should expect.
resources :groups, only: [:new, :create, :show, :destroy] do
resources :procedures
end
In your controller, do this:
def new
#group = Group.find(params[:group_id])
#procedure = #group.procedures.new
end
And you'd link to the new page like this
<%= link_to 'Create a Procedure', new_group_procedure_path(#group), class: 'btn btn-default btn-small' %>
To further add to Swards answer, you're looking at nested resources...
#config/routes.rb
resources :groups, except: [:edit, :update] do
resources :procedures #-> url.com/groups/:group_id/procedures/new
end
--
When you send a request to your server, you're requesting a "resource".
As defined by the HTTP spec,
The client submits an HTTP request message to the server. The server, which provides resources such as HTML files and other content, or performs other functions on behalf of the client
This is why the Rails routes have resources directives.
In your case, the resources you're requesting need to be dependent on another "parent" resource, hence you'd use the "nested" pattern. This provides a parameter of the "parent" var in your dependent controller:
#app/controllers/procedures_controller.rb
class ProceduresController < ApplicationController
before_action :set_group
def new
#procedure = #group.procedures.new
end
private
def set_group
#group = Group.find params[:group_id]
end
end
--
Your linking method would work from Swards recommendation; you may also benefit from polymorphic_path:
<%= link_to 'Create a Procedure', new_polymorphic_path([#group, :procedure]), class: 'btn btn-default btn-small' %>
So I just made one of my objects a nested resource of my user object. Now all of my links don't work and my index won't show. I am getting the error:
/views/photos/index.html.haml where line #8 raised:
No route matches {:action=>"show", :controller=>"photos", :id=>nil,
:user_id=>nil} missing required keys: [:id, :user_id]
with this line being where its finding the issue:
= link_to photo.title, user_photo_path(#user, #photos)
This is my controller for my photos object:
class PhotosController < ApplicationController
before_action :find_photo, only: [:show, :edit, :update, :destroy, :upvote, :downvote]
before_action :authenticate_user!, except: [:index, :show]
def index
#photos = Photo.all.order(:cached_weighted_score => :desc)
end
def show
#comments = Comment.where(photo_id: #photo)
#photo = Photo.find(params[:id])
end
My routes look like this:
Rails.application.routes.draw do
devise_for :users
root 'photos#index'
resources :users do
resources :photos do
member do
get "like", to: "photos#upvote"
get "unlike", to: "photos#downvote"
end
resources :comments
end
end
end
This is my user controller:
class UsersController < ApplicationController
def show
#user = User.find_by(params[:id])
#photos= #user.photos.order(:cached_weighted_score => :desc)
end
end
finally the view that is generating the error code:
.container
.row
.col-lg-12
%h1.page-header Most Popular Photos
- #photos.each do |photo|
.thumbnail.col-lg-3.col-md-4.col-xs-6.thumb
%h2
= link_to photo.title, user_photo_path(#user, #photo)
= link_to (image_tag photo.image.url(:small)), photo
%p
= photo.get_likes.size
Likes
= link_to "Add New Photo", new_photo_path
Any help is appreciated. My last change was adding the photos route into below the users route.
2nd arg needs to be a photo instance from the loop not #photo which is probably nil:
= link_to photo.title, user_photo_path(#user, photo)
UPDATE 1: You also need to load up #user in PhotosController#show:
#user = User.find_by(params[:user_id])
I am still very much new to rails, but cant seem to get a grasp on this route
show.html.erb
<%= link_to "up", vote_movie_review_path(#review, type: "up"), method: "post" %>
rake route
vote_movie_review POST /movies/:movie_id/reviews/:id/vote(.:format) reviews#vote
routes.rb
Rails.application.routes.draw do
devise_for :users
resources :movies do
resources :reviews do
member { post :vote }
end
end
reviews_controller.rb
class ReviewsController < ApplicationController
before_action :set_reviews, only: [:show, :edit, :update, :destroy]
before_action :set_movie
before_action :authenticate_user!
respond_to :html
def index
#reviews = Review.all
respond_with(#reviews)
end
def show
end
def vote
value - params[:type] == "up" ? 1 : -1
#review = Review.find(params[:id])
#review.add_evaluation(:votes, value, current_user)
redirect_to :back, notice: "thanks for the vote"
end
You are using nested routes, so you need to pass movie object also.use like this vote_movie_review_path(#movies, #review, type: "up").
Check your routes, it showing /movies/:movie_id/reviews/:id/vote while the way you are calling it will generate like /reviews/id with method post and for it you have not defined any routes.