Background
I am following an outdated beginner's Ruby course and got stuck. During this course, I am building a Ruby on rails application similar to Yelp, so it is for listing and reviewing restaurants. Currently, I am linking the reviews to the restaurants.
My ruby version is: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin22]
My rails version is: Rails 7.0.4.2
Steps
I am linking the reviews to the restaurants by executing the following steps:
Run rails generate migration AddRestaurantIDToReviews restaurant_id:integer
Run rake db:migrate
Add belongs_to :restaurant to reviews.rb
Add has_many :reviews to restaurants.rb
Check rails routes
Adjusted routes.rb file
Adjusted reviews_form.html.erb
Adjusted review_controller.rb file
set_restaurant and set_restaurant before action
Add #review statement for restaurant_id (line …)
Removed links that point to old URLs
Restart server
Error message
This resulted in the following error: undefined method `reviews_path' for #ActionView::Base:0x00000000025800 and this is triggered by this line of code: <%= form_with(model: [#resturant, #review], local: true) do |form| %> (from the reviews _form.html.erb file). In this thread a similar issue is explained, but I still can't figure it out.
Could someone help me with this? And if you need more info, please let me know!
Review.rb
class Review < ApplicationRecord
belongs_to :user
belongs_to :restaurant
end
Restaurant.rb
class Restaurant < ApplicationRecord
mount_uploader :image, ImageUploader
has_many :reviews
end
Routes.rb
Rails.application.routes.draw do
devise_for :users
resources :restaurants do
resources :reviews, except: [:show, :index]
end
get 'pages/about'
get 'pages/contact'
root 'restaurants#index'
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
# root "articles#index"
end
**Routes**
` Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
restaurant_reviews POST /restaurants/:restaurant_id/reviews(.:format) reviews#create
new_restaurant_review GET /restaurants/:restaurant_id/reviews/new(.:format) reviews#new
edit_restaurant_review GET /restaurants/:restaurant_id/reviews/:id/edit(.:format) reviews#edit
restaurant_review PATCH /restaurants/:restaurant_id/reviews/:id(.:format) reviews#update
PUT /restaurants/:restaurant_id/reviews/:id(.:format) reviews#update
DELETE /restaurants/:restaurant_id/reviews/:id(.:format) reviews#destroy
restaurants GET /restaurants(.:format) restaurants#index
POST /restaurants(.:format) restaurants#create
new_restaurant GET /restaurants/new(.:format) restaurants#new
edit_restaurant GET /restaurants/:id/edit(.:format) restaurants#edit
restaurant GET /restaurants/:id(.:format) restaurants#show
PATCH /restaurants/:id(.:format) restaurants#update
PUT /restaurants/:id(.:format) restaurants#update
DELETE /restaurants/:id(.:format) restaurants#destroy
pages_about GET /pages/about(.:format) pages#about
pages_contact GET /pages/contact(.:format) pages#contact
root GET / restaurants#index
turbo_recede_historical_location GET /recede_historical_location(.:format) turbo/native/navigation#recede
turbo_resume_historical_location GET /resume_historical_location(.:format) turbo/native/navigation#resume
turbo_refresh_historical_location GET /refresh_historical_location(.:format) turbo/native/navigation#refresh
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create
rails_sendgrid_inbound_emails POST /rails/action_mailbox/sendgrid/inbound_emails(.:format) action_mailbox/ingresses/sendgrid/inbound_emails#create
rails_mandrill_inbound_health_check GET /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#health_check
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
rails_mailgun_inbound_emails POST /rails/action_mailbox/mailgun/inbound_emails/mime(.:format) action_mailbox/ingresses/mailgun/inbound_emails#create
rails_conductor_inbound_emails GET /rails/conductor/action_mailbox/inbound_emails(.:format) rails/conductor/action_mailbox/inbound_emails#index
POST /rails/conductor/action_mailbox/inbound_emails(.:format) rails/conductor/action_mailbox/inbound_emails#create
new_rails_conductor_inbound_email GET /rails/conductor/action_mailbox/inbound_emails/new(.:format) rails/conductor/action_mailbox/inbound_emails#new
edit_rails_conductor_inbound_email GET /rails/conductor/action_mailbox/inbound_emails/:id/edit(.:format) rails/conductor/action_mailbox/inbound_emails#edit
rails_conductor_inbound_email GET /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#show
PATCH /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#update
PUT /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#update
DELETE /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#destroy
new_rails_conductor_inbound_email_source GET /rails/conductor/action_mailbox/inbound_emails/sources/new(.:format) rails/conductor/action_mailbox/inbound_emails/sources#new
rails_conductor_inbound_email_sources POST /rails/conductor/action_mailbox/inbound_emails/sources(.:format) rails/conductor/action_mailbox/inbound_emails/sources#create
rails_conductor_inbound_email_reroute POST /rails/conductor/action_mailbox/:inbound_email_id/reroute(.:format) rails/conductor/action_mailbox/reroutes#create
rails_conductor_inbound_email_incinerate POST /rails/conductor/action_mailbox/:inbound_email_id/incinerate(.:format) rails/conductor/action_mailbox/incinerates#create
rails_service_blob GET /rails/active_storage/blobs/redirect/:signed_id/*filename(.:format) active_storage/blobs/redirect#show
rails_service_blob_proxy GET /rails/active_storage/blobs/proxy/:signed_id/*filename(.:format) active_storage/blobs/proxy#show
GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs/redirect#show
rails_blob_representation GET /rails/active_storage/representations/redirect/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations/redirect#show
rails_blob_representation_proxy GET /rails/active_storage/representations/proxy/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations/proxy#show
GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations/redirect#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create`
Review _form.html.erb
<%= form_with(model: [#resturant, #review], local: true) do |form| %>
<% if review.errors.any? %>
<div style="color: red">
<h2><%= pluralize(review.errors.count, "error") %> prohibited this review from being saved:</h2>
<ul>
<% review.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= form.label :rating, style: "display: block" %>
<%= form.number_field :rating, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :comment, style: "display: block" %>
<%= form.text_area :comment, class: "form-control" %>
</div>
<div>
<%= form.submit class: "btn btn-primary" %>
</div>
<% end %>
Reviews_controller.rb
class ReviewsController < ApplicationController
before_action :set_review, only: %i[ edit update destroy ]
before_action :set_restaurant
before_action :authenticate_user!
# GET /reviews/new
def new
#review = Review.new
end
# GET /reviews/1/edit
def edit
end
# POST /reviews or /reviews.json
def create
#review = Review.new(review_params)
#review.user_id = current_user.id
#review.restaurant_id = #restaurant.id
respond_to do |format|
if #review.save
format.html { redirect_to root_path, notice: "Review was successfully created." }
format.json { render :show, status: :created, location: #review }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reviews/1 or /reviews/1.json
def update
respond_to do |format|
if #review.update(review_params)
format.html { redirect_to review_url(#review), notice: "Review was successfully updated." }
format.json { render :show, status: :ok, location: #review }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reviews/1 or /reviews/1.json
def destroy
#review.destroy
respond_to do |format|
format.html { redirect_to reviews_url, notice: "Review was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_review
#review = Review.find(params[:id])
end
def set_restaurant
#restaurant = Restaurant.find(params[:restaurant_id])
end
# Only allow a list of trusted parameters through.
def review_params
params.require(:review).permit(:rating, :comment)
end
end
The url: restaurant_reviews_path addition to the form_with made the difference.
<%= form_with(model: #review, url: restaurant_reviews_path, local: true) do |form| %>
Related
When I go to delete a post I get the error "Couldn't find Post with 'id'=testuser". I think this is a routing error as I believe the id being ran should be that of the Post and not the User? I can't work it out. I can create posts but can't delete or edit for the same reasons.
I can provide more information if needed.
The extracted source in PostController#destroy is where:
def set_post
#work = Work.find(params[:id])
routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { :registrations => "registrations" }
resources :posts do
end
# Define route URL
root 'pages#index'
# Define routes for Pages
get '/home' => 'pages#home'
get '/user/:id' => 'pages#profile'
get '/new' => 'posts#new'
Pages_controller.rb
class PagesController < ApplicationController
def index
end
def home
end
def profile
if (User.find_by_username(params[:id]))
#username = params[:id]
else
redirect_to root_path, :notice=> "User not found!"
end
#posts = Post.all.where("user_id = ?", User.find_by_username(params[:id]).id)
#newPost = Post.new
end
end
Posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def create
#post = Post.new(post_params)
#post.user_id = current_user.id #assign post to the user who created it
respond_to do |f|
if (#post.save)
f.html { redirect_to "", notice: "Post created!" }
else
f.html { redirect_to "", notice: "Error: Post Not Saved" }
end
end
end
def show
end
def edit
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Your 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
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to root_path, notice: 'Post was successfully deleted.' }
format.json { head :no_content }
end
end
private
def set_post
#post = Post.find(params[:id])
end
def post_params #allows certain data to be passed via form
params.require(:post).permit(:user_id, :title, :description, :image)
end
end
Profile.html.erb
...
<%= link_to('Delete', post_path, :method => :delete) %>
...
Terminal
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) registrations#cancel
user_registration POST /users(.:format) registrations#create
new_user_registration GET /users/sign_up(.:format) registrations#new
edit_user_registration GET /users/edit(.:format) registrations#edit
PATCH /users(.:format) registrations#update
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root GET / pages#index
home GET /home(.:format) pages#home
GET /user/:id(.:format) pages#profile
connect GET /connect(.:format) pages#connect
help GET /help(.:format) pages#help
messages GET /messages(.:format) pages#messages
new GET /new(.:format) posts#new
You did not pass id or instance in link of delete
<%= link_to('Delete', post_path, :method => :delete) %>
Should be pass a post instance on the delete link so that in find it find the post
<%= link_to('Delete', post_path(post), :method => :delete) %>
or
<%= link_to('Delete', post_path(post.id), :method => :delete) %>
In my Rails 4 app, there are four models:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many: :posts
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
With this routing:
Rails.application.routes.draw do
root to: 'pages#home'
devise_for :users, :path => 'account'
resources :calendars do
resources :posts, shallow: true
end
end
Which gives these routes:
Prefix Verb URI Pattern Controller#Action
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root GET / pages#home
new_user_session GET /account/sign_in(.:format) devise/sessions#new
user_session POST /account/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /account/sign_out(.:format) devise/sessions#destroy
user_password POST /account/password(.:format) devise/passwords#create
new_user_password GET /account/password/new(.:format) devise/passwords#new
edit_user_password GET /account/password/edit(.:format) devise/passwords#edit
PATCH /account/password(.:format) devise/passwords#update
PUT /account/password(.:format) devise/passwords#update
cancel_user_registration GET /account/cancel(.:format) devise/registrations#cancel
user_registration POST /account(.:format) devise/registrations#create
new_user_registration GET /account/sign_up(.:format) devise/registrations#new
edit_user_registration GET /account/edit(.:format) devise/registrations#edit
PATCH /account(.:format) devise/registrations#update
PUT /account(.:format) devise/registrations#update
DELETE /account(.:format) devise/registrations#destroy
user_confirmation POST /account/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /account/confirmation/new(.:format) devise/confirmations#new
GET /account/confirmation(.:format) devise/confirmations#show
user_unlock POST /account/unlock(.:format) devise/unlocks#create
new_user_unlock GET /account/unlock/new(.:format) devise/unlocks#new
GET /account/unlock(.:format) devise/unlocks#show
calendar_posts GET /calendars/:calendar_id/posts(.:format) posts#index
POST /calendars/:calendar_id/posts(.:format) posts#create
new_calendar_post GET /calendars/:calendar_id/posts/new(.:format) posts#new
GET /posts/:id/edit(.:format) posts#edit
GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
calendars GET /calendars(.:format) calendars#index
POST /calendars(.:format) calendars#create
new_calendar GET /calendars/new(.:format) calendars#new
edit_calendar GET /calendars/:id/edit(.:format) calendars#edit
calendar GET /calendars/:id(.:format) calendars#show
PATCH /calendars/:id(.:format) calendars#update
PUT /calendars/:id(.:format) calendars#update
DELETE /calendars/:id(.:format) calendars#destroy
And finally, here is the content of posts_controller.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
#calendar = Calendar.find(params[:calendar_id])
#post = #calendar.posts.create(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to calendar_path(#calendar), 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 calendar_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
#calendar = Calendar.find(params[:calendar_id])
#post.destroy
respond_to do |format|
format.html { redirect_to calendar_path(#calendar), 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(:date, :time, :subject, :format, :copy, :media)
end
end
I keep running into a similar error.
Issue #1: when I try to delete a post from the show.html.erb calendar view:
<h2><%= #calendar.name %> Calendar</h2>
<h3>Posts</h3>
<% if #calendar.posts.any? %>
<table>
<tr>
<th>Date</th>
<th>Time</th>
<th>Subject</th>
<th>Format</th>
<th>Copy</th>
<th>Media</th>
</tr>
<% #calendar.posts.each do |post| %>
<tr>
<td><%= post.date %></td>
<td><%= post.time %></td>
<td><%= post.subject %></td>
<td><%= post.format %></td>
<td><%= post.copy %></td>
<td><%= post.media %></td>
<td><%= link_to 'View', post %></td>
<td><%= link_to 'Update', edit_post_path(post) %></td>
<td><%= link_to 'Delete', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
</table>
<% end %>
...
I get:
ActiveRecord::RecordNotFound in PostsController#destroy
Couldn't find Calendar with 'id'=
Issue #2: when I try to update a post from the edit.html.erb post view:
<h1>Editing Post</h1>
<%= render 'form' %>
<%= link_to 'Show', #post %> |
<%= link_to 'Back', posts_path %>
I get:
ActiveRecord::RecordNotFound in PostsController#update
Couldn't find Calendar with 'id'=
Issue #3: when I try to go back to the show.html.erb calendar view from the show.html.erb post view:
<div>
<p>Date</p>
<%= #post.date %>
</div>
<div>
<p>Time</p>
<%= #post.time %>
</div>
<div>
<p>Subject</p>
<%= #post.subject %>
</div>
<div>
<p>Format</p>
<%= #post.format %>
</div>
<div>
<p>Copy</p>
<%= #post.copy %>
</div>
<div>
<p>Media</p>
<%= #post.media %>
</div>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Back', posts_path %>
I get:
ActiveRecord::RecordNotFound in PostsController#show
Couldn't find Calendar with 'id'=
If my interpretation of the errors is correct, every time, the problem seems to be that I cannot retrieve the id of the calendar the post belongs to.
In other words, I cannot retrieve the parent (calendar) id from the child (post) controller.
I believe this is a problem related to my nested shallow resources and the way my links are built in the views.
I can't figure out how to make these links work.
If you could provide me with the solution — and most importantly the reasoning — for one of the three situations described above, I would most definitely be able to come up with the solution for the other two.
Any idea?
I found a solution to each one of my three issues.
Issue #1: I replaced:
format.html { redirect_to calendar_path(#calendar), notice: 'Post was successfully destroyed.' }
with:
format.html { redirect_to calendar_path(#post.calendar_id), notice: 'Post was successfully destroyed.' }
in posts_controller.rb.
Issue #2: I replaced:
<%= link_to 'Back', posts_path %>
with:
<%= link_to 'Back', calendar_path(#post.calendar_id) %>
in the edit.html.erb posts view.
Issue #3: I replaced:
<%= link_to 'Back', posts_path %>
with:
calendar_path(#post.calendar_id)
in the show.html.erb posts view
I'm trying to associate "Notes" with "Account one the same page (show.html.erb) once the note is created. However, once I create the note for the associated account I get undefined local variable or method `accounts' for NotesController:0x0000000545e1d8"
Notes were being created fine up until the point of association.
with #account = accounts.find(params[:account_id]) highlighted on like 65.
**Parameters:** (on debug page)
{"utf8"=>"✓",
"authenticity_token"=>"gm6gJ3mYDDVmDHnsB2JqhOtOY1Lc9n3P7Yuq9gpqdo4=",
"note"=>{"comment"=>"1221211212"},
"commit"=>"Create Note",
"account_id"=>"1"}
Running Rails 4.1.8 and
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]
note_colltroler.rb
class NotesController < ApplicationController
before_action :set_note, only: [:edit, :update, :destroy]
before_action :set_account
before_action :authenticate_user!
before_action :check_user, only: [:edit, :update, :destroy]
# GET /notes/new
def new
#note = note.new
end
# GET /notes/1/edit
def edit
end
# POST /notes
# POST /notes.json
def create
#note = note.new(note_params)
#note.user_id = current_user.id
#note.account_id = #account.id
respond_to do |format|
if #note.save
format.html { redirect_to #account, notice: 'note was successfully created.' }
format.json { render :show, status: :created, location: #note }
else
format.html { render :new }
format.json { render json: #note.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /notes/1
# PATCH/PUT /notes/1.json
def update
respond_to do |format|
if #note.update(note_params)
format.html { redirect_to account_path(#account), notice: 'note was successfully updated.' }
format.json { render :show, status: :ok, location: #note }
else
format.html { render :edit }
format.json { render json: #note.errors, status: :unprocessable_entity }
end
end
end
# DELETE /notes/1
# DELETE /notes/1.json
def destroy
#note.destroy
respond_to do |format|
format.html { redirect_to account_path(#account), notice: 'note was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_note
#note = note.find(params[:id])
end
def set_account
#account = accounts.find(params[:account_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def note_params
params.require(:note).permit(:comment)
end
end
note.rb
class Note < ActiveRecord::Base
belongs_to :user
belongs_to :account
end
account.rb
class Account < ActiveRecord::Base
belongs_to :program
has_many :notes
end
Rake Routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
account_notes POST /accounts/:account_id/notes(.:format) notes#create
new_account_note GET /accounts/:account_id/notes/new(.:format) notes#new
edit_account_note GET /accounts/:account_id/notes/:id/edit(.:format) notes#edit
account_note PATCH /accounts/:account_id/notes/:id(.:format) notes#update
PUT /accounts/:account_id/notes/:id(.:format) notes#update
DELETE /accounts/:account_id/notes/:id(.:format) notes#destroy
accounts GET /accounts(.:format) accounts#index
POST /accounts(.:format) accounts#create
new_account GET /accounts/new(.:format) accounts#new
edit_account GET /accounts/:id/edit(.:format) accounts#edit
account GET /accounts/:id(.:format) accounts#show
PATCH /accounts/:id(.:format) accounts#update
PUT /accounts/:id(.:format) accounts#update
DELETE /accounts/:id(.:format) accounts#destroy
programs GET /programs(.:format) programs#index
POST /programs(.:format) programs#create
new_program GET /programs/new(.:format) programs#new
edit_program GET /programs/:id/edit(.:format) programs#edit
program GET /programs/:id(.:format) programs#show
PATCH /programs/:id(.:format) programs#update
PUT /programs/:id(.:format) programs#update
DELETE /programs/:id(.:format) programs#destroy
pages_index GET /pages/index(.:format) pages#index
root GET / pages#index
For Notes show.html.erb
<div class="row">
<div class="col-md-3">
<p>
<strong>First name:</strong>
<%= #account.first_name %>
</p>
<p>
<strong>Last name:</strong>
<%= #account.last_name %>
</p>
<p>
<strong>Program:</strong>
<%= #account.program.program %>
</p>
<p>
<strong>Address:</strong>
<%= #account.address %>
</p>
<p>
<strong>Phone:</strong>
<%= #account.phone %>
</p>
<p>
<strong>Created:</strong>
<%= #account.created_at %>
</p>
<%= link_to "Write a Note", new_account_note_path(#account), class: "btn btn-primary" %>
</div>
<div class="col-md-9">
<% #notes.each do |note| %>
<p><%= note.comment %></p>
<% end %>
<%= link_to 'Edit', edit_account_path(#account), class: "btn btn-link" %> |
<%= link_to 'Back', account_path, class: "btn btn-link" %>
</div>
</div>
Instead of
#account = accounts.find(params[:account_id])
try
#account = Account.find(params[:account_id])
Learn more about .find and other query methods here. Most of them are called on an
Side Note:
As #apneadiving pointed out, you generally want to use some sort of authorisation. I don't think you want users to be able to edit accounts of other users. With your current implementation this is possible by simply experimenting in with the account and note ids in the url (e.g. by getting /accounts/1/notes/2/edit any user can edit note 2 of account 1).
Consider scoping records for the current user. One approach is described here.
in
def set_account
#account = accounts.find(params[:account_id])
end
accounts is not defined
I'm learning Rails. I've got an app that has "Ideas", which have "Comments"
I've created the comments using this guide (https://gorails.com/episodes/comments-with-polymorphic-associations)
I am using the 'Ancestry' gem to attempt make them nested using this guide on railscasts (http://railscasts.com/episodes/262-trees-with-ancestry)
Anyways I'm getting this error "ActionController::RoutingError (uninitialized constant Comments):"
This is where I'm getting the error – when I hit the "Reply" link
<h3> Comments </h3>
<% #idea.comments.each do |comment| %>
<div>
<%= comment.body %>
<div class="actions">
<%= link_to "Reply", new_comment_path(:parent_id => comment) %>
</div>
</div>
<% end %>
The above is being rendered on the "Ideas/show.html" page
<p id="notice"><%= notice %></p>
<p>
<strong>Description:</strong>
<%= #idea.description %>
</p>
<%= render partial: "comments/comments", locals: {commentable: #idea} %>
<%= render partial: "comments/form", locals: {commentable: #idea} %>
<% if #idea.user == current_user %>
<%= link_to 'Edit', edit_idea_path(#idea) %>
<% end %>
<%= link_to 'Back', ideas_path %>
I want to send them here to "Comments/new" which is the same as my form page
<%= form_for [commentable, Comment.new] do |f| %>
<div class="form-group">
<%= f.hidden_field :parent_id %>
<%= f.text_area :body, class: "form-control", placeholder: "Add a comment here" %>
</div>
<%= f.submit class: "btn btn-primary" %>
<% end %>
Routes.rb
Rails.application.routes.draw do
resources :ideas do
resources :comments, module: :ideas
end
devise_for :users
root 'ideas#index'
get "about" => "pages#about"
get "new_comment" => "comments/new"
end
Comments_controller.rb
class CommentsController < ApplicationController
before_action :authenticate_user!
def new
#comment = Comment.new(:parent_id => params[:parent_id])
end
def create
#comment = #commentable.comments.new comment_params
#comment.user = current_user
#comment.save
redirect_to #commentable, notice: "Your comment was posted"
end
private
def comment_params
params.require(:comment).permit(:body)
end
end
Ideas_controller.rb
class IdeasController < ApplicationController
before_action :set_idea, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
before_action :correct_user, only: [:edit, :update, :destroy]
respond_to :html
def index
#ideas = Idea.all
end
def show
end
def new
#idea = Idea.new
#idea.comments.build
respond_with(#idea)
end
def edit
end
def create
#idea = current_user.ideas.build(idea_params)
if #idea.save
redirect_to #idea, notice: "Idea was successfully created."
else
render :action => 'new'
end
end
def update
if #idea.update(idea_params)
redirect_to #idea, notice: "Your idea has been updated"
else
render action: 'edit'
end
end
def destroy
#idea.destroy
redirect_to ideas_url
end
private
def set_idea
#idea = Idea.find(params[:id])
end
def correct_user
#idea = current_user.ideas.find_by(id: params[:id])
redirect_to ideas_path, notice: "You can't edit this" if #idea.nil?
end
def idea_params
params.require(:idea).permit(:description)
end
end
Any help would be much appreciated, thank you.
EDIT _ Added my routes
idea_comments GET /ideas/:idea_id/comments(.:format) ideas/comments#index
POST /ideas/:idea_id/comments(.:format) ideas/comments#create
new_idea_comment GET /ideas/:idea_id/comments/new(.:format) ideas/comments#new
edit_idea_comment GET /ideas/:idea_id/comments/:id/edit(.:format) ideas/comments#edit
idea_comment GET /ideas/:idea_id/comments/:id(.:format) ideas/comments#show
PATCH /ideas/:idea_id/comments/:id(.:format) ideas/comments#update
PUT /ideas/:idea_id/comments/:id(.:format) ideas/comments#update
DELETE /ideas/:idea_id/comments/:id(.:format) ideas/comments#destroy
ideas GET /ideas(.:format) ideas#index
POST /ideas(.:format) ideas#create
new_idea GET /ideas/new(.:format) ideas#new
edit_idea GET /ideas/:id/edit(.:format) ideas#edit
idea GET /ideas/:id(.:format) ideas#show
PATCH /ideas/:id(.:format) ideas#update
PUT /ideas/:id(.:format) ideas#update
DELETE /ideas/:id(.:format) ideas#destroy
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root GET / ideas#index
about GET /about(.:format) pages#about
new_comment GET /new_comment(.:format) comments/new#new_comment
I'm sorry but I am fairly new to Rails and I can't seem to understand what the problem is. I am building an online forum and want my users to not only be able to edit their own post but also any comments that they may create. I keep getting a: undefined method `comment_path' for #<#:0x007fe5b6b0cbd0>. Any ideas?
routes:
PostitTemplate::Application.routes.draw do
root to: 'posts#index'
get '/register', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
get '/logout', to: 'sessions#destroy'
resources :users, only: [:create, :edit, :update]
resources :posts, except: [:destroy] do
member do
post 'vote'
end
resources :comments, only: [:create, :edit, :update] do
member do
post 'vote'
end
end
end
resources :categories, only: [:new, :create]
end
my comments edit.html.erb:
<div class="page-header">
<h2>Update Comment<small> - looks like you need some updating!</small></h2>
</div>
<h3><%= #post.description %></h3>
<%= render 'shared_partials/errors', errors_obj: #comment %>
<div class="well">
<%= form_for #comment do |f| %>
<%= f.text_area :body, :class=> "input", :placeholder=> "Comment goes here", :rows => "6" %>
</br>
<div class="button">
<%= f.submit "Create a comment", class: 'btn btn-primary' %>
</div>
<% end %>
</div>
comments_controller:
class CommentsController < ApplicationController
before_action :require_user
def create
#post = Post.find(params[:post_id])
#comment = Comment.new(params.require(:comment).permit(:body))
#comment.post = #post
#comment.creator = current_user
if #comment.save
flash[:notice] = "Your comment was created!"
redirect_to post_path(#post)
else
render 'posts/show'
end
end
def edit
#comment = Comment.find(params[:id])
#post = Post.find(params[:post_id])
end
def update
#comment = Comment.find(params[:id])
if #comment.update(comment_params)
flash[:notice] = "You updated your comment!"
redirect_to post_comments_path
else
render :edit
end
end
end
rake routes:
Prefix Verb URI Pattern Controller#Action
root GET / posts#index
register GET /register(.:format) users#new
login GET /login(.:format) sessions#new
POST /login(.:format) sessions#create
logout GET /logout(.:format) sessions#destroy
users POST /users(.:format) users#create
edit_user GET /users/:id/edit(.:format) users#edit
user PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
vote_post POST /posts/:id/vote(.:format) posts#vote
vote_post_comment POST /posts/:post_id/comments/:id/vote(.:format) comments#vote
post_comments POST /posts/:post_id/comments(.:format) comments#create
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment PATCH /posts/:post_id/comments/:id(.:format) comments#update
PUT /posts/:post_id/comments/:id(.:format) comments#update
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
categories POST /categories(.:format) categories#create
new_category GET /categories/new(.:format) categories#new
Because your comments are nested resources, you'll need to pass the #post into your call to form_for().
form_for [#post, #comment] do |f|