I'm sure that there is a simple solution to this problem, but I can't for the life of me see what I am doing wrong - it's been a few months since I've worked on a Rails project, I must be forgetting something important.
I'm just trying to create a basic Rails form, but I am getting a no method path error when I navigate to the new form page.
This is for my Report model...
routes.rb
resources :report, only: [:new, :create], path_names: {new: ''}
report_controller.rb
def new
#report = Report.new
end
report/new.html.erb
<%= form_for #report do |f| %>
<% end %>
Navigating to http://localhost:3000/report yields
undefined method `reports_path'
Just to be comprehensive, here's the model...
class Report < ActiveRecord::Base
belongs_to :user
belongs_to :weather
belongs_to :feature
end
and the routes
report_index POST /report(.:format) report#create
new_report GET /report(.:format) report#new
I'm sure this is an amateur mistake... but I can't see what it is!
You need to change your routes to include a :show path if you want to be able to go to /report.
The path that I believe you are looking for is localhost:3000/reports/new
Oh for the love of god. It was a pluralization issue. The files should appear and be named as follows:
routes.rb
resources :reports, only: [:new, :create], path_names: {new: ''}
reports_controller.rb
class ReportsController < ApplicationController
def new
#report = Report.new
end
end
And the view files should all be in a folder called 'reports', not 'report'. The model is just the singular report.rb.
Related
I am very new to rails and I don't know much about where my problem lies. Just started a few days ago and right now I am trying to add comments to a specific post. Well, technically these are not comments but more of logs added to a certain request when other people have interacted with the request like Request A has log B, log C, log D so its basically the same as a comment sytem.
I already can create the logs and display them but my main problem is showing the right logs for the right request. My logs already have the correct request id but I don't know how to get the specific logs to display for the specific request
This is my historys_controller.rb
class HistorysController < ActionController::Base
before_action :require_login
def index
#historys = History.where(job_order: 1)
end
def require_login
unless session['user_credentials_id']
redirect_to '/'
end
end
end
It is still set as 1 as a temporary placeholder and trying something like
History.where(job_order: #job_order.id)
and
History.where(job_order: params [:id])
does not work so what should I put there?
EDIT
history.rb
class History < ApplicationRecord
belongs_to :job_order, polymorphic: true
belongs_to :actor, class_name: "User"
end
routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'user_sessions#new'
get '/sign_in', to: 'user_sessions#new', as: :sign_in
get '/signup' => 'users#signup', as: 'signup_user'
delete '/sign_out', to: 'user_sessions#destroy', as: :sign_out
post '/register' => 'users#register', as: 'register_user'
get '/users/activate/:id' => 'users#activate', as: 'activate_user'
get '/users/deactivate/:id' => 'users#deactivate', as: 'deactivate_user'
get '/job_order_tracking_system' => 'job_orders#dashboard', as: 'job_order_tracking_system'
get '/job_orders/approve_job_order/:id' => 'job_orders#approve_job_order', as: 'approve_job_order'
get '/job_orders/reject_job_order/:id' => 'job_orders#reject_job_order', as: 'reject_job_order'
get '/job_orders/start_job_order/:id' => 'job_orders#start_job_order', as: 'start_job_order'
get '/job_orders/done_job_order/:id' => 'job_orders#done_job_order', as: 'done_job_order'
get '/job_orders/cancel_job_order/:id' => 'job_orders#cancel_job_order', as: 'cancel_job_order'
resources :job_orders do
resources :historys
end
resources :users
resources :offices
resources :user_sessions, only: [:create, :destroy]
resources :notifications do
collection do
post :mark_as_read
end
end
# resources :historys
end
you want the histories for a specific job order?
Do
class JobOrder < ApplicationRecord
has_many :histories
end
Then you can get all the related histories with
#job_order.histories
And in your view you can do somthing like...
<% #job_order.histories.each do |history| %>
<%= history.name %>
<%= history.comment %>
<br/>
<% end %>
Incidentally, use the correct spelling for the plural of "history"... your controller should be HistoriesController Rails is smarter than you realise.
I also noticed you've got some spacing between params and [:id]. It should look this way: params[:id].
I have Q+A model inside an events model and having issue with understanding how the nested routes work. I'm getting a No route matches {:action=>"create", :controller=>"event_questions" and missing required keys: [:event_id]`
My question form sits inside my show.hrml.erb for my event model right now. Some of the relationship stuff is from neo4j gem so it isn't standard but the issue shouldn't be related to that. From what I know, I am posting to /events/events_id/event_questions
events_controller.rb
def show
#event = Event.find(params[:id])
#event_question = EventQuestion.new
end
event.rb
has_many :out, :event_questions, type: 'questions_of'
event_question.rb
has_one :in, :events, origin: :event_questions
events/show.html.erb
<%= form_for [:event, #event_question] do |f| %>
#form stuff
<% end %>
event_questions_controller.rb
def create
#event_question = EventQuestion.new(event_question_params)
if #event_question.save
#event = Event.find(params[:event_id])
#event_question.update(admin: current_user.facebook_id)
#event_question.events << #event
redirect_to #event
else
redirect_to :back
end
end
routes.rb
resources :events do
resources :event_questions, only: [:create, :destroy]
end
I think it's in your routes. Change it to look like this:
resources :events do
resources :questions, controller: 'event_questions`, only: [:create, :destroy]
end
That'll give you http://youraddress/event/:event_id/questions and put it in the expected controller. Make sure it's event_questions.rb and not events_questions.rb. From terminal, also run rake routes and it'll show you the actions, paths, and controllers responsible for them.
Got it to work with
form_for(#event_question, :url => event_event_questions_path(#event)) do |f|
I'm not sure how to pass the #event via the other way (in the question), but assuming you can, both methods should work.
I know it is a typical problem. But I was just trying the routing in rails and I get this error:
uninitialized constant UsersController
And I don't know well where is the problem.
The resume of my app is a simple application of a library, where users can book books and see the books they've booked.
Here is my routes.rb
Brickstest2::Application.routes.draw do
resources :books
root "pages#home"
get "home", to: "pages#home", as: "home"
get "inside", to: "pages#inside", as: "inside"
devise_for :users
namespace :admin do
root "base#index"
resources :users
end
resources :books do
get :book_a_book, :as => "reserve"
end
resources :users do
get :booked_books, :as => "reserved", :on => :member
end
end
Actually When I do rake routes I get:
reserved_user_path
GET /users/:id/booked_books(.:format) users#booked_books
And in users_controllers.rb I have:
def booked_books
#user = User.first(params[:user_id])
#return unless #user == current_user
#books = Books.where(:user = #user)
end
The link to booked_books:
<%= link_to "My books", user_reserved_path(:user_id => current_user.id)%>
And finally my users/booked_books.html.erb:
<h1>My books</h1>
<%= #books.each do |book|%>
<p><%= book.name %>
<% end %>
Thanks in advance.
Have you declared a controller for your User resource that subclasses ApplicationController?
# app/controllers/users_controller.rb
class UsersController < ApplicationController
Note that the precise naming convention for a plural resource route for the User model is UsersController (note the s). I'm guessing that you've named your controller class UserController, which won't work for your use-case.
UPDATE:
Since you've declared a controller namespace, you'll want to declare your controller class like so:
# app/controllers/admin/users_controller.rb
class Admin::UsersController < ApplicationController
This should resolve any uninitialized constant UsersController errors involving your namespace.
I am facing an issue with inherited_resources when using a polymorphic nested resource, one of whose parents is a namespaced controller. Here is an abstract example:
# routes.rb
resources :tasks do
resources :comments
end
namespace :admin do
resources :projects do
resources :comments
end
end
# comments_controller.rb
class CommentsController < InheritedResources::Base
belongs_to :projects, :tasks, :polymorphic => true
end
When I access /admin/projects/1/comments, I get this error:
ActionController::RoutingError at /admin/projects/1/comments
uninitialized constant Admin::CommentsController
Now if I define the controller as Admin::CommentsController, I would need to move the file under controllers/admin which will in turn throw up an error for the url /tasks/1/comments
Is there a way I can fix this?
Why not keep CommentsController where it is and make a separate controller for admin in admin/comments_controller.rb? that inherits from it?
class Admin::CommentsController < CommentsController
before_filter :do_some_admin_verification_stuff
# since we're inheriting from CommentsController you'll be using
# CommentsController's actions by default - if you want
# you can override them here with admin-specific stuff
protected
def do_some_admin_verification_stuff
# here you can check that your logged in used is indeed an admin,
# otherwise you can redirect them somewhere safe.
end
end
The short answer to your question is mentioned here in the Rails Guide.
Basically you have to tell the route mapper which controller to use because the default is not there:
#routes.rb
namespace :admin do
resources :projects do
resources :comments, controller: 'comments'
end
end
That will take care of your routing problem, which is actually probably not related to Inherited Resources.
On the other hand, I have been unable to use Inherited Resources as well, in cases of a nested controller inside a namespace. I've moved away from that gem because of this.
I created something that might be interesting to you: a controller concern that will define all of the useful route helpers that inherited resources gives, in a way that accounts for namespaces. It's not smart enough to handle optional or multiple parentage, but it spared me a lot of typing long method names.
class Manage::UsersController < ApplicationController
include RouteHelpers
layout "manage"
before_action :authenticate_admin!
before_action :load_parent
before_action :load_resource, only: [:show, :edit, :update, :destroy]
respond_to :html, :js
create_resource_helpers :manage, ::Account, ::User
def index
#users = parent.users
respond_with [:manage, parent, #users]
end
def show
respond_with resource_params
end
def new
#user = parent.users.build
respond_with resource_params
end
# etc...
end
And then inside my views:
td = link_to 'Show', resource_path(user)
td = link_to 'Edit', edit_resource_path(user)
td = link_to 'Destroy', resource_path(user), data: {:confirm => 'Are you sure?'}, :method => :delete
Hope that helps!
class CommentsController < ApplicationController
def create
#commentable= context_object()
#comment = #commentable.comments.build(params[:comment].merge(:user_id => current_user.id))
if #comment.save
respond_to do |format|
format.js
end
else
render :action => 'new'
end
end
private
def context_object
params[:constraint][:context_type].singularize.classify.constantize.find( context_id )
end
def context_id
params["#{ params[:constraint][:context_type].singularize }_id"]
end
end
This commenting module has served me well but I ran into a hitch this morning, possibly because of my use of nested resources. Essentially, I now have a URL like:
/projects/3/albums/6/attachments/84
When I comment on that page, I get the error:
ActiveRecord::RecordNotFound (Couldn't find Project without an ID):
app/controllers/comments_controller.rb:102:in `context_object'
app/controllers/comments_controller.rb:14:in `create'
My routes file looks like:
resources :projects do
resources : albums do
resources :attachments
end
end
resources :attachments do
resources :comments, :only => [:create, :update,:destroy],
:constraint => {:context_type => "conversations"}
end
Any ideas on how I can get the commenting module to play nicely with commenting on project>Album>Attachment ?
Thanks for the input,
Posting this as an answer in order not to clutter the comments to the original question.
Since you don't have the requirement to keep attachments available via /attachments - making the second resources block useless, do something like this:
resources :projects do
resources :albums do
resources :attachments do
resources :comments, :only => [:create, :update,:destroy],
:constraint => {:context_type => "conversations"}
end
end
end
That's going to change your routes helpers (_path and _url), go through your controller(s) and view(s) and change them to reflect your new helpers.
Specifically, attachment_comments_path becomes project_album_attachment_comments_path.
The full list of routes for those models can be viewed by running rake routes in a console. I'd also recommend you take a closer look to the Rails routing guide.