开发者

How to make a dead link reporter?

I want to make a button on my website that a user can click on to report at external dead link. The link do I have in my link column that is in my item table.

I want to create an simple email notice that have the ID of the item and the link. I was thinking creating an form and some sort of controller that could handle the form.

My view should look something like this:

<% for items in @items %>
        <%= simple_form_for @items] do |f| %>
        <%= f.hidden field :id, :value => 'item.id' %>
        <%= f.hidden field :url, :value => 'item.link %>
        <%= f.button :submit, :value => 'report broken link' %>
    <% end %>
 <% end %>

The id and the url inputs should not be viewable just a link like "report broken开发者_运维知识库 link". A controller should take the two params and send me an email.

How do I create a simple dead external links reporter?


Your question could be a bit more specific, but you probably want to use something like Net:HTTP and something similar to this:

  uri = URI.parse(url)
  response = nil

  begin
    Net::HTTP.start(uri.host, uri.port) do |http|
      response = http.head(uri.path.size > 0 ? uri.path : "/")
    end
  rescue => e 
    ...
  end

  # handle redirects if you need to
  if response.is_a?(Net::HTTPRedirection)
   ...
  end

  if response.code == '404'
    ...
  end


For a simple broken link reporter I would just utilize a helper for dry code, like the following :

module ApplicationHelper
  def report_broken_link_for( id )
    link_to "report broken link", {:controller => "reporting", :action => "report_broken_link", :id => id}, :class => "broken_link_reporter_link", :remote => true
  end

I suggest that you wouldn't need to use a form, but if you feel so inclined you can modify the helper. Add/remove parameters as you see fit, but the item id would probably be simple enough, you can lookup the actual link in the back end. Simply use it in your views :

<% @items.each do |item| %> 
  <%= link_to item.url %>
  <%= report_broken_link_for item.id %><br/>
<% end %>

Use some ujs to make sure they don't repost it :

$('.broken_link_reporter_link')
   .live('ajax:success', function(evt, data, status, xhr){
      $(this).replaceWith("thanks!");
 });

Hope this helps.


It seems that you simply want your users to be able to report dead links without doing the actual check. You do not need a form for that, a

link_to "text", :controller=>ctrl, :action=>actname, :id=>item_id, :method=>:post

should be sufficient, not to mention that it would look nicer and cause less problems with styling, etc. In Rails 3 this would look different, I think :remote=>true instead of :method=>:post.

The controller/action you call with this link_to should construct and send mail (read about ActionMailer). In fact, this controller can actually check whether the link is dead or not, as M. Kohl suggested.

Note that you can pass more than :controller, :action and :id. All of what you pass will be available in the params array in the controller/action.


As you are explaining it, you just need a mailer that sends user reported broken links, nothing unusual.

Other options include creating a rake task which iterates over your links, and reports broken ones, with code similar to Michael Kohl. This doesn't require a user triggered mailer:

# In lib/tasks/ (rake links:test)
require 'net/http'    
namespace :links do
  desc "Test for broken links in DB."
  task :test => :environment do |t, args|
    count = 0
    Entries.all.each do |e|
      count += 1
      # is_live? implementation is similar to Michael's
      puts "ERR: #{e.url} (Entry id: #{e.id})" unless is_live?(e.url)
    end
    puts "#{count} tested links."
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜