2011-07-19 20 views
2

我正在構建一個來自過時指南的URL縮短,這意味着很多調試。我第一次使用縮短劑時,效果很好。如何解決'列標識符不唯一'?

現在,在提交的鏈接時,它返回此錯誤:「列標識符不是唯一的」

private 
     def self.create_link(original) 
     url = Url.create(:original => original) 
     if Link.first(:identifier => url.id.to_i.to_s(36)).nil? or !DIRTY_WORDS.include? url.id.to_i.to_s(36) 
      link = Link.new(:identifier => url.id.to_i.to_s(36)) 
      link.url = url 
      link.save 
      return link 
     else 
      create_link(original) 
     end 
     end 
    end 

該錯誤是指該特定的行。

link.save 

在此先感謝您的幫助!

這些是模型。

class Url 
    include DataMapper::Resource 
    property :id,  Serial 
    property :original, String, :length => 255 
    belongs_to :link 
end 



class Link 
    include DataMapper::Resource 
    property :identifier, String, :key => true 
    property :created_at, DateTime 
    has 1, :url 
    has n, :visits 

    def self.shorten(original, custom=nil) 
    url = Url.first(:original => original) 
    return url.link if url 
    link = nil 
    if custom 
     raise 'Someone has already taken this custom URL, sorry' unless 
    Link.first(:identifier => custom).nil? 
     raise 'This custom URL is not allowed because of profanity' if 
    DIRTY_WORDS.include? custom 
     transaction do |txn| 
     link = Link.new(:identifier => custom) 
     link.url = Url.create(:original => original) 
     link.save 
     end 
    else 
     transaction do |txn| 
     link = create_link(original) 
     end 
    end 
    return link 
    end 

    private 
    def self.create_link(original) 
    url = Url.create(:original => original) 
    if Link.first(:identifier => url.id.to_i.to_s(36)).nil? or !DIRTY_WORDS.include? url.id.to_i.to_s(36) 
     link = Link.new(:identifier => url.id.to_i.to_s(36)) 
     link.url = url 
     link.save 
     return link 
    else 
     create_link(original) 
    end 
    end 
end 


class Visit 
    include DataMapper::Resource 

    property :id,   Serial 
    property :created_at, DateTime 
    property :ip,   IPAddress 
    property :country,  String 
    belongs_to :link 

    after :create, :set_country 

    def set_country 
    xml = RestClient.get "http://api.hostip.info/get_xml.php?ip=#{ip}" 
    self.country = XmlSimple.xml_in(xml.to_s, { 'ForceArray' => false})['featureMember']['Hostip']['countryAbbrev'] 
    self.save 
    end 

    def self.count_days_bar(identifier,num_of_days) 
    visits = count_by_date_with(identifier, num_of_days) 
    data, labels = [], [] 
    visits.each {|visit| data << visit[1]; labels << "#{visit[0].day}/#{visit[0].month}" } 
    "http://chart.apis.google.com/chart?chs=820x180&cht=bvs&chxt=x&chco=a4b3f4&chm=N,000000,0,-1,11&chxl=0:|#{labels.join('|')}&chds=0,#{data.sort.last+10}&chd=t:#{data.join(',')}" 
    end 

    def self.count_country_chart(identifier,map) 
    countries, count = [], [] 
    count_by_country_with(identifier).each {|visit| countries << visit.country; count << visit.count} 
    chart = {} 
    chart[:map] = "http://chart.apis.google.com/chart?chs=440x220&cht=t&chtm=#{map}&chco=FFFFFF,a4b3f4,0000FF&chld=#{countries.join('')}&chd=t:#{count.join(',')}" 
    chart[:bar] = "http://chart.apis.google.com/chart?chs=320x240&cht=bhs&chco=a4b3f4&chm=N,000000,0,-1,11&chbh=a&chd=t:#{count.join(',')}&chxt=x,y&chxl=1:|#{countries.reverse.join('|')}" 
    return chart 
    end 

    def self.count_by_date_with(identifier,num_of_days) 
    visits = repository(:default).adapter.query("SELECT date(created_at) as date, count(*) as count FROM visits where link_ = '#{identifier}' and created_at between CURRENT_DATE-#{num_of_days} and CURRENT_DATE+1 group by date(created_at)") 
    dates = (Date.today-num_of_days..Date.today) 
    results = {} 
    dates.each { |date| 
     visits.each { |visit| results[date] = visit.count if visit.date == date } 
     results[date] = 0 unless results[date] 
    } 
    results.sort.reverse 
    end 

    def self.count_by_country_with(identifier) 
    respository(:default).adapter.query("SELECT country, count(*) as count FROM visits where link_identifier = '#{identifier}' group by country") 
    end 
end 
+1

請發表您的計劃.rb – s84

回答

2

很好,直到有人更瞭解編鐘...... 我不知道Ruby on Rails的或Ruby,但我知道數據庫,這聽起來完全像一個主鍵驗證錯誤。我懷疑你的link.id字段必須是唯一的,並且第二次運行該程序時它會生成相同的ID。賠率是好的,你需要創建一個唯一的ID或放寬在ID字段的禁忌,以允許重複(這可能會導致問題,當你去檢索事情的ID)。

+0

你幾乎是對的。 ActiveRecord有一個驗證列唯一性的DSL方法。它與獨特的數據庫索引並不完全一樣,但試圖達到類似的目的。 OP已經指定他希望'標識符'列是唯一的,但是當它在保存之前驗證對象時,數據庫中已經存在具有相同值的記錄。 –

+0

我已經發布了模型和一切指向你們所說的。但我使用DataMapper(而不是ActiveRecord)和Sinatra – Dru