Reputation: 6068
I have been following along with a RailsCasts episode, and am trying to make articles taggable. Then I want to make tags clickable on articles show.html page, so that users can find other related articles. I am using Rails 4. However, I have been getting the following error:
ActiveRecord::RecordNotFound in ArticlesController#show
Couldn't find Article without an ID
Extracted source (around line #43):
def show
@article = Article.find(params[:id])
end
I then tried to make the following changes, which I observed after looking at the RailsCast code:
articles_controller.rb
[...]
def show
if params[:tag]
@articles = Article.tagged_with(params[:tag])
else
@article = Article.find(params[:id])
end
end
Which gave me the error upon clicking a tag on a working show page:
http://localhost:x000/tags/pizza
NoMethodError in Articles#show
undefined method 'title' for nil:NilClass
<div id="article-title">
<h1>
<p>
<%= @article.title %></span>
</p>
</h1>
</div>
Which seems odd to me, since the title method works just fine otherwise. Everything else works on the site, the tags save and can be edited in the articles edit page, but finding all articles with a specific tag isn't working.
=== Relevant code areas:
_form.html
<p>
<%= f.label :keyword_Tags %><br/>
<%= f.text_field :tag_list %> <span class="gray-text"><em>Separated by commas; single tag has no spaces, only-dashes </em></span>
</p>
routes.rb
Network::Application.routes.draw do
resources :libraries
get "libraries/show"
devise_for :authors, :controllers => {:registrations => "authors/registrations"}
get 'tags/:tag', to: 'articles#show', as: :tag
devise_scope :author do
get 'signup', to: 'devise/registrations#new'
get 'signin', to: 'devise/sessions#new'
# get 'logout', to: 'devise/sessions#destroy'
end
resources :relationships, only: [:create, :destroy]
get "landing_page/index"
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
resources :articles do
resources :comments
end
# You can have the root of your site routed with "root"
root 'landing_page#index'
get '/:id', to: 'libraries#show'
end
article.rb
class Article < ActiveRecord::Base
has_many :comments, dependent: :destroy
belongs_to :author
acts_as_taggable
acts_as_taggable_on :tag_list
validates :title, presence: true,
length: { minimum: 5 }
validates :text, presence: true,
length: { minimum: 2 }
validates :article_start, presence: true,
length: {minimum: 10}
end
[num]_create_articles.rb
class CreateArticles < ActiveRecord::Migration
def change
create_table :articles do |t|
t.string :title
t.time :era
t.string :chapter
t.date :article_start
t.text :text
t.string :tag_list
t.timestamps
end
end
end
controller
class ArticlesController < ApplicationController
before_filter :authenticate_author!, only: [:create, :new, :edit, :update, :destroy]
#added destroy to above, not in Treebook
def index
@articles = Article.all
end
def new # diff between new and create?
@article = Article.new
end
def create
@article = Article.new(article_params)
#respond_to do|format|
if @article.save
redirect_to @article
else
render 'new'
end
end
#end #for respond_to; noticed in "What is a join table"
def show #show, being an action
@article = Article.find(params[:id])
end
def edit
@article = Article.find(params[:id])
end
def update
@article = Article.find(params[:id])
if @article.update(article_params)
redirect_to @article
else
render 'edit'
end
end
def destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to articles_path
end
private
def article_params
params.require(:article).permit(:title, :text, :author_id, :article_start, :era, :chapter, :address, :tag_list)
end
end
Request
Parameters:
{"tag"=>"open"}
Upvotes: 0
Views: 442
Reputation: 53038
Update ArticlesController
actions show
and index
as below:
def show
@article = Article.find(params[:id])
end
def index
if params[:tag]
@articles = Article.tagged_with(params[:tag])
else
@articles = Article.all
end
end
Also, update the routes.rb
:
Replace
get 'tags/:tag', to: 'articles#show', as: :tag
With
get 'tags/:tag', to: 'articles#index', as: :tag ## It should go to index action not show
Upvotes: 1