Reputation: 1312
So i'm trying to record the number of times a link is clicked but can't get over the last hurdle.
I have the following so far:
config/routes.rb
resources :papers do
resources :articles do
resources :clicks
end
end
click.rb
class Click < ActiveRecord::Base
belongs_to :article, counter_cache: true
validates :ip_address, uniqueness: {scope: :article_id}
end
clicks_controller.rb
class ClicksController < ApplicationController
def create
@article = Article.find(params[:article_id])
@click = @article.clicks.new(ip_address: request.ip)
@click.save
end
end
article.rb
class Article < ActiveRecord::Base
has_many :clicks
end
schema.rb
create_table "clicks", force: true do |t|
t.integer "article_id"
t.string "ip_address"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "articles", force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.text "title"
t.string "url"
t.integer "paper_id"
t.integer "clicks_count"
end
index.html.erb -- articles
<% @articles.each do |article| %>
<div class="articles col-md-4">
<%= link_to article.url, target: '_blank' do %>
<h4><%= article.title %></h4>
<h5><%= article.paper.name.upcase %></h5>
<h6><%= article.created_at.strftime("%d %B %y") %></h6>
<% end %>
Firstly, does this setup look correct, does anyone see where i may have gone wrong? Secondly, what i don't know how to set up my view so that when the existing link is clicked the click is registered and the count goes up?
Thanks
Upvotes: 0
Views: 1282
Reputation: 1312
Solved with the following.
clicks_controller.rb
Original:
def create
@article = Article.find(params[:article_id])
@click = @article.clicks.new(ip_address: request.ip)
@click.save
end
end
Amended:
def create
@article = Article.find(params[:article_id])
@click = @article.clicks.new(ip_address: request.ip)
@click.save
redirect_to @article.url
end
end
index.html.erb -- articles
Original:
<%= link_to article.url, target: '_blank' do %>
Amended:
<%= link_to paper_article_views_path(article.id, article), method: :post, target: '_blank' do %>
Also, i edited the original question to include the routes.rb
file.
Upvotes: 1
Reputation: 3371
In my opinion, you should do 2 things :
1) Set all the methods for "clicks" into a Model
For example, you can remove your ClicksController
and add this :
class Article
def create_click(ip_address)
self.clicks.create({ :ip_address => ip_address })
end
end
A little note with this code : you have a uniqueness validation in your code. Indeed, when a click already exists for an article and an ip address, the create
method will return false. Do not use create!
instead, or it will raise an exception.
2) Add a filter :
You can simply add a filter in your ArticlesController
. At each show
, it will create a click
instance for the viewed article
class ArticlesController
before_filter :create_click, :only => [ :show ]
def create_click
@article.create_click(ip_address)
end
end
Upvotes: 0