I have a view which lists all my comparisons
index.html.erb
<% #comparisons.each do |comparison| %>
<div class="col-xs-6 col-sm-4 col-md3">
<p><%= comparison.title %></p>
<p><%= comparison.id %></p>
<p><%= comparison.description %></p>
</div>
<% end %>
Up to now, all is going well : title, description and id are displayed for each comparison.
I tried to add a Show link :
<% #comparisons.each do |comparison| %>
<div class="col-xs-6 col-sm-4 col-md3">
<p><%= comparison.title %></p>
<p><%= comparison.id %></p>
<p><%= comparison.description %></p>
<p><%= link_to 'Show', comparison_path(comparison) %></p>
</div>
<% end %>
But now, when I load index.html.erb I have this error :
No route matches {:action=>"show", :controller=>"comparisons", :format=>nil, :id=>nil, :locale=>#<Comparison id: 1, title: "coucou", description: "", created_at: "2015-07-04 10:33:47", updated_at: "2015-07-04 10:33:47", user_id: 1>} missing required keys: [:id]
I don't understand why...
comparisons_controller.rb
class ComparisonsController < ApplicationController
before_action :set_comparison, only: [ :show ]
skip_before_action :authenticate_user!, only: [ :index, :show ]
def index
#comparisons = policy_scope(Comparison)
end
def show
end
def new
#comparison = current_user.comparisons.new
authorize #comparison
end
def create
#comparison = current_user.comparisons.new(comparison_params)
authorize #comparison
if #comparison.save
# redirect_to comparison_path(#comparison)
# redirect_to #comparison
render :show
else
render :new
end
end
private
def set_comparison
#comparison = Comparison.find(params[:id])
authorize #comparison
end
def comparison_params
params.require(:comparison).permit(:title, :description, :user_id)
end
end
By the way, as you can see, in create action, I have not been able to use a redirect_to. But render :show works : the show.html.erb view is loaded.
Any risks to use render rather redirect_to ?
My 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
page GET (/:locale)/pages/:id high_voltage/pages#show {:locale=>/fr/}
comparisons GET (/:locale)/comparisons(.:format) comparisons#index {:locale=>/fr/}
POST (/:locale)/comparisons(.:format) comparisons#create {:locale=>/fr/}
new_comparison GET (/:locale)/comparisons/new(.:format) comparisons#new {:locale=>/fr/}
comparison GET (/:locale)/comparisons/:id(.:format) comparisons#show {:locale=>/fr/}
home GET /home(.:format) redirect(301, /)
root GET / high_voltage/pages#show {:id=>"home"}
routes.rb
Rails.application.routes.draw do
devise_for :users
scope '(:locale)', locale: /fr/ do
get 'pages/:id' => 'high_voltage/pages#show', :as => :page, :format => false
resources :comparisons, only: [ :index, :show, :new, :create ]
end
end
Thanks in advance for your help.
Seeing from your routes files, it looks to me that to construct a route, you need two parameters - locale and id. Since you are using comparison_path(comparison), rails is assuming that the first parameter you are passing refers to locale.
To construct a correct route, use a cleaner way to construct a route - like this:
comparison_path(locale: 'en', id: comparison.id)
Previous answers made me realize I had a routing issue with i18n : locale parameter was not considered in urls building.
In application_controller.rb I still have
before_action :set_locale
private
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
I add this second method which automatically add the locale parameter to urls
def default_url_options
{ locale: I18n.locale == I18n.default_locale ? nil : I18n.locale }
end
Now, it works fine.
Thanks for your help.
Alternatively you can use like this:
<% #comparisons.each do |comparison| %>
<div class="col-xs-6 col-sm-4 col-md3">
<p><%= comparison.title %></p>
<p><%= comparison.id %></p>
<p><%= comparison.description %></p>
<p><%= link_to 'Show', comparison %></p>
</div>
<% end %>
It seems to me using :shallow_path would be the answer. From the documentation.
The :path, :as, :module, :shallow_path and :shallow_prefix options all default to the name of the namespace.
I think this will remove (/:locale) from the raked routes
scope '(:locale)', locale: /fr/, :shallow_path => '(:locale)' do
get 'pages/:id' => 'high_voltage/pages#show', :as => :page, :format => false
resources :comparisons, only: [ :index, :show, :new, :create ]
end
Related
I'm trying to hook up a link that will take users from a lesson show page (that lists a bunch of words) to a form to edit one of the listed words. I have a teacher namespace, such that teachers have many lessons and lessons have many words. Before working on a form to edit the word, the lesson show page is breaking when I add the link to what would be the edit form: ActionController::UrlGenerationError in Teacher::Lessons#show, No route matches {:action=>"edit", :controller=>"teacher/words", :id=>nil, :lesson_id=>#<Word id: 19, term: "la casa", reference: "house", lesson_id: 6, created_at: "2016-06-05 23:19:19", updated_at: "2016-06-05 23:19:19", image: "house.jpeg", sound: "test.mp3">} missing required keys: [:id]
What am I missing in regards to setting the edit_teacher_lesson_word link?
Rails.application.routes.draw do
devise_for :users
root 'static_pages#index'
resources :lessons, only: [:index, :show]
resources :words, only: [:show]
namespace :teacher do
resources :lessons, only: [:show, :new, :edit, :create, :update] do
resources :words, only: [:new, :edit, :create, :update]
end
end
end
teacher/words_controller:
class Teacher::WordsController < ApplicationController
before_action :authenticate_user!
before_action :require_authorized_for_current_lesson
def new
#word = Word.new
end
def edit
#word = Word.find(params[:id])
end
def create
#word = current_lesson.words.create(word_params)
if #word.valid?
redirect_to teacher_lesson_path(current_lesson)
else
render :new, status: :unprocessable_entity
end
end
private
def require_authorized_for_current_lesson
if current_lesson.user != current_user
render text: 'Unauthorized', status: :unauthorized
end
end
helper_method :current_lesson
def current_lesson
#current_lesson ||= Lesson.find(params[:lesson_id])
end
def word_params
params.require(:word).permit(:term, :reference, :image, :sound)
end
end
teacher/lessons_controller:
class Teacher::LessonsController < ApplicationController
before_action :authenticate_user!
before_action :require_authorized_for_current_lesson, only: [:show, :edit, :update]
def show
#lesson = Lesson.find(params[:id])
end
def new
#lesson = Lesson.new
end
def edit
#lesson = Lesson.find(params[:id])
end
def create
#lesson = current_user.lessons.create(lesson_params)
if #lesson.valid?
redirect_to teacher_lesson_path(#lesson)
else
render :new, status: :unprocessable_entity
end
end
def update
current_lesson.update_attributes(lesson_params)
redirect_to teacher_lesson_path(current_lesson)
end
private
def require_authorized_for_current_lesson
if current_lesson.user != current_user
render text: "Unauthorized", status: :unauthorized
end
end
def current_lesson
#current_lesson ||= Lesson.find(params[:id])
end
def lesson_params
params.require(:lesson).permit(:title, :description, :subject, :difficulty)
end
end
teacher/lessons/show:
<div class ="booyah-box col-xs-10 col-xs-offset-1">
<br>
<p class="text-center"><%= #lesson.description %></p>
<br>
<div class="text-center">
<%= link_to 'Edit Lesson', edit_teacher_lesson_path(#lesson), class: 'btn btn-primary' %>
<%= link_to 'Student View', lesson_path(#lesson), class: 'btn btn-warning' %>
<%= link_to 'My Lessons', '#', class: 'btn btn-success' %>
<%= link_to 'All Lessons', lessons_path, class: 'btn btn-info' %>
</div>
<hr>
<h3>Vocabulary in This Lesson</h3>
<%= link_to 'Add word', new_teacher_lesson_word_path(#lesson), class: 'btn btn-primary btn-lg pull-right' %>
<ul>
<% #lesson.words.each do |word| %>
<li>
<b><%= word.term %></b> means <i><%= word.reference %></i>
<%= link_to 'Edit', edit_teacher_lesson_word_path(word), class: 'btn btn-primary' %>
</li>
<% end %>
</ul>
</div>
rake routes:
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 / static_pages#index
lessons GET /lessons(.:format) lessons#index
lesson GET /lessons/:id(.:format) lessons#show
word GET /words/:id(.:format) words#show
teacher_lesson_words POST /teacher/lessons/:lesson_id/words(.:format) teacher/words#create
new_teacher_lesson_word GET /teacher/lessons/:lesson_id/words/new(.:format) teacher/words#new
edit_teacher_lesson_word GET /teacher/lessons/:lesson_id/words/:id/edit(.:format) teacher/words#edit
teacher_lesson_word PATCH /teacher/lessons/:lesson_id/words/:id(.:format) teacher/words#update
PUT /teacher/lessons/:lesson_id/words/:id(.:format) teacher/words#update
teacher_lessons POST /teacher/lessons(.:format) teacher/lessons#create
new_teacher_lesson GET /teacher/lessons/new(.:format) teacher/lessons#new
edit_teacher_lesson GET /teacher/lessons/:id/edit(.:format) teacher/lessons#edit
teacher_lesson GET /teacher/lessons/:id(.:format) teacher/lessons#show
PATCH /teacher/lessons/:id(.:format) teacher/lessons#update
PUT /teacher/lessons/:id(.:format) teacher/lessons#update
looks like you're passing a Word where it's expecting a Lesson. see this part of the error message: :lesson_id=>#<Word id: 19,
I'm guessing, but probably this is the wrong line of code:
edit_teacher_lesson_word_path(word)
your route file says this about that route:
edit_teacher_lesson_word GET /teacher/lessons/:lesson_id/words/:id/edit(.:format)
the : indicates what things you need to pass in order to create a valid route... and here you need both :lesson_id as well as :id and you are only passing one of those (and it's getting confused about which one).
Usually you'd instantiate this route with both lesson and word eg:
edit_teacher_lesson_word_path(#lesson, word)
Try that (or variations on it) to get it to work.
Trying to add simple search functionality to my app so anyone can search articles. After adding the code ,it does not display the search results on the index. But the url shows http://localhost:3000/articles?utf8=%E2%9C%93&search=hello&commit=Search
index.html.erb
<p>This is the articles placeholder</p>
<%= form_tag articles_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search" %>
<% end %>
<% #articles.each do |article| %>
<h2><%= link_to article.title, article %></h2>
<p>Published at
<%= article.created_at.strftime('%b %d, %Y') %>
</p>
<p>
<%= truncate(article.content, length: 200) %>
</p>
<% end %>
articles controller
class ArticlesController < ApplicationController
before_action :find_article, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#articles = Article.search(params[:search])
#articles = Article.all.order("created_at DESC")
end
def new
#article = current_user.articles.build
end
def show
end
def create
#article = current_user.articles.build(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def edit
end
def update
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
def destroy
#article.destroy
redirect_to root_path
end
private
def article_params
params.require(:article).permit(:title, :content)
end
def find_article
#article = Article.find(params[:id])
end
end
article.rb
class Article < ActiveRecord::Base
belongs_to :user
def self.search(search)
if search
where(["name LIKE ?", "%#{search}%"])
else
all
end
end
end
rake routes
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
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
root GET / articles#index
You're overwrite the search by then calling Article.all.order("created_at DESC") and assigning that to the #articles variable
#articles = Article.search(params[:search])
#articles = Article.all.order("created_at DESC")
So you want
#articles = Article.search(params[:search]).order("created_at DESC")
because your search method will return all if the parameters aren't present anyway.
This is a basic error and lots of people have ask similar questions, such as:
ActiveRecord::RecordNotFound in PostsController#show
ActiveRecord::RecordNotFound in PostsController#show clicking a link
However, none of them actually helped me solve the issue I am facing now.
In my Rails 4 app, I have 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
Here are my routes:
Rails.application.routes.draw do
root to: 'pages#home'
devise_for :users, :path => 'account'
resources :calendars do
resources :posts, shallow: true
end
end
Here is the problem: when I am on a calendar, for instance http://localhost:3000/calendars/11, I have all the posts that belong to this calendar displayed, with Show, Edit and Destroy links alongside each post.
When I click the Edit link, I am taken to http://localhost:3000/posts/11/edit.5* and I get the following error:
ActiveRecord::RecordNotFound in PostsController#edit
Couldn't find Post with 'id'=11
# 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.
Note: I don't know why I keep getting this weird url, with .5 at the end.
Here is the content of my PostsController:
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
#calendar = Calendar.find(params[:calendar_id])
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
#calendar = Calendar.find(params[:calendar_id])
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to calendar_path(#calendar), 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
UPDATE: as per #Nathan's comment, here is the edit.html.erb view:
<h1>Editing Post</h1>
<%= render 'form' %>
<%= link_to 'Show', #post %> |
<%= link_to 'Back', posts_path %>
and here is the _form.html.erb partial used in it:
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<p>
<%= f.label :date %><br>
<%= f.date_select :date %>
</p>
<p>
<%= f.label :time %><br>
<%= f.time_select :time %>
</p>
<p>
<%= f.label :subject %><br>
<%= f.text_field :subject %>
</p>
<p>
<%= f.label :format %><br>
<%= f.text_field :format %>
</p>
<p>
<%= f.label :copy %><br>
<%= f.text_area :copy %>
</p>
<p>
<%= f.label :media %><br>
<%= f.text_field :media %>
</p>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
UPDATE 2: as per #danielricecodes' answer, here is the result of running rake routes in Terminal:
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
UPDATE 3: as per #Nathan's second comment, here is the content of my 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(#calendar, post) %></td>
<td><%= link_to 'Delete', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
</table>
<% end %>
<% else %>
<p>This calendar does not contain any post yet: just create one with the form below.</p>
<% end %>
<h3>Add a post to <%= #calendar.name %> Calendar:</h3>
<%= form_for([#calendar, #calendar.posts.build]) do |f| %>
<p>
<%= f.label :date %><br>
<%= f.date_select :date %>
</p>
<p>
<%= f.label :time %><br>
<%= f.time_select :time %>
</p>
<p>
<%= f.label :subject %><br>
<%= f.text_field :subject %>
</p>
<p>
<%= f.label :format %><br>
<%= f.text_field :format %>
</p>
<p>
<%= f.label :copy %><br>
<%= f.text_area :copy %>
</p>
<p>
<%= f.label :media %><br>
<%= f.text_field :media %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit', edit_calendar_path %> |
<%= link_to 'Back', calendars_path %>
UPDATE 4: here are the routes when I remove the shallow option from the post resource:
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
MacBook-Pro-de-Thibaud:calendy TXC$ rake routes
Prefix Verb URI Pattern Controller#Action
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
edit_calendar_post GET /calendars/:calendar_id/posts/:id/edit(.:format) posts#edit
calendar_post GET /calendars/:calendar_id/posts/:id(.:format) posts#show
PATCH /calendars/:calendar_id/posts/:id(.:format) posts#update
PUT /calendars/:calendar_id/posts/:id(.:format) posts#update
DELETE /calendars/:calendar_id/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
Any idea how I can fix this?
Two arguments are being passed in for a named path (edit_post) which expects one argument. This is causing problems when the controller action set_post tries to determine which :id to use when looking up the record to set as #post.
It's also why you have that .5 mysteriously appended to the end of your URL — I believe 5 is the :id of post (in that context), and 11 is the :id of #calendar.
edit_post_path only needs to know the :id of the post you want to edit, so you can fix this by changing <%= link_to 'Update', edit_post_path(#calendar, post) %> to <%= link_to 'Update', edit_post_path(post) %> (note the removal of #calendar).
If you really do want to edit this post as a resource nested under calendar (at the path /calendars/<calendar_id>/posts/<post_id>/edit), take a look at your config/routes.rb. The shallow: true option (which you used when nesting :posts under :calendars) is what's keeping the nested :edit path from being created.
You'll need to have that nested :edit path available, and then you can pass two arguments just as you are now (something like edit_calendar_post_path(#calendar, post)).
The error makes me think there's a problem with the link you're building in your view template. I'd help more but I do not see the View file or the output from rake routes. Without those two things, its hard for me to tell you why your app is generating a funny url - but it usually means the view template is not calling the correct url_helper.
The problem his related to the edit_post_path. With shallow nesting, the edit route is outside of the parent scope. The .5 is the Post ID being added to the url, but not as a valid url param because there's already an ID param from the calendar. Based on the way your routes are setup, it looks like you would need to set the id as a param in the link, like this:
link_to "edit post", edit_post_path(post)
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 trying to add comment functionality of my Reddit clone. This is the comments controller that creates a comments and adds it to a post.
class CommentsController < ApplicationController
def new
#topic = Topic.find(params[:topic_id])
#post = Post.find(params[:id])
#comment = Comment.new
#authorize #comment # from include Pundit in the application controller, authorize is an inherited method
end
def create
#topic = Topic.find(params[:topic_id])
#post = Post.find(params[:id])
#comment = current_user.comments.build(comment_params)
end
private
def comment_params
params.require(:comment).permit(:text)
end
end
I'm trying to add a comments field for every post page by using a form partial that looks like this:
<%= form_for [topic, post] do |f| %>
<%= form_group_tag(comment[:text]) do %>
<%= f.label :text %>
<%= f.text_area :text, rows: 10, class: 'form-control', placeholder: "Enter your comment" %>
<% end %>
<div class = "form-group">
<%= f.submit "Save", class: 'btn btn-success' %>
</div>
<% end %>
This form partial should appear at the post.show.html.erb so I put it there
<h1><%= markdown #post.title %></h1>
<div class="row"> <!-- what others are there besides row? -->
<div class="col-md-8">
<p><%= markdown #post.body %></p>
</div>
<div class="col-md-4">
<% if policy(#post).edit? %>
<%= link_to "Edit", edit_topic_post_path(#topic, #post), class: 'btn btn-success' %>
<% end %>
</div>
<div class="col-md-8">
<%= render partial: 'comments/form', locals: { topic: #topic, post: #post, text: #post.comments.new } %>
</div>
</div>
but I'm getting a NameError for my 'comment' on the form_group_tag line. Most of what I defined here comes from my code for adding new posts, which seemed to work. Is there something missing here?
I fixed my name error by adding comments to the form_for line, but I'm getting NoMethodError for my topic,post,comment path, so I thought it'd be helpful to add what rake routes is pulling up.
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
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
user PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
topic_posts POST /topics/:topic_id/posts(.:format) posts#create
new_topic_post GET /topics/:topic_id/posts/new(.:format) posts#new
edit_topic_post GET /topics/:topic_id/posts/:id/edit(.:format) posts#edit
topic_post GET /topics/:topic_id/posts/:id(.:format) posts#show
PATCH /topics/:topic_id/posts/:id(.:format) posts#update
PUT /topics/:topic_id/posts/:id(.:format) posts#update
DELETE /topics/:topic_id/posts/:id(.:format) posts#destroy
topics GET /topics(.:format) topics#index
POST /topics(.:format) topics#create
new_topic GET /topics/new(.:format) topics#new
edit_topic GET /topics/:id/edit(.:format) topics#edit
topic GET /topics/:id(.:format) topics#show
PATCH /topics/:id(.:format) topics#update
PUT /topics/:id(.:format) topics#update
DELETE /topics/:id(.:format) topics#destroy
post_comments POST /posts/:post_id/comments(.:format) comments#create
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
about GET /about(.:format) welcome#about
root GET / welcome#index
BTW: how does this routes.rb file look?
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:update]
resources :topics do
resources :posts, except: [:index]
end
resources :posts do
resources :comments, only: [:create]
end
end
Try:
<%= render partial: 'comments/form', locals: { topic: #topic, post: #post, comment: #post.comments.new } %>
...
<%= form_for [post, comment] do |f| %>
<%= f.label :text %>
<%= f.text_area :text, rows: 10, class: 'form-control', placeholder: "Enter your comment" %>
<%= f.submit "Save", class: 'btn btn-success' %>
<% end %>
...
If it does not help, try to temporary comment form_group_tag and send error here
It seems like you're sending the comment down to the partial as text.
... locals: { topic: #topic, post: #post, text: #post.comments.new } %>
^^^^
And by the way you're not saving the comment in the create action.