has n,属于Sinatra的DataMapper

时间:2012-09-05 02:12:31

标签: ruby-on-rails ruby sinatra datamapper

在O'Reilly的书的帮助下,我正在使用Sinatra和DataMapper构建一个url缩短服务的克隆。当我通过提交缩短网址进行测试时,我收到此错误

NoMethodError - undefined method `visits' for nil:NilClass:
第31行的

。看起来Link类没有访问属性,但是,正如您将从下面的类定义中看到的那样,关系是这样的,我应该可以调用link.visits

我正在使用最新版本的DataMapper。有人可以建议修复此问题吗?

get '/:short_url' do 
  link = Link.first(:identifier => params[:short_url])
  link.visits << Visit.create(:ip => get_remote_ip(env))   #this is line 32
  link.save
  redirect link.url.original, 301
end

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


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

3 个答案:

答案 0 :(得分:1)

我相信这就是你的问题所在:

link = Link.first(:identifier => params[:short_url])

我敢打赌linknil

当您收到类似

的错误时
NoMethodError - undefined method `visits' for nil:NilClass:

这是说你试图在对象visits上调用方法nil。您希望在visits对象上调用方法Link

如果您想查找记录是否存在或创建新记录,请尝试以下操作:

Link.first_or_create(:identifier => params[:short_url])

答案 1 :(得分:1)

创建新访问的更好方法:

link.visits.new(:ip => get_remote_ip(env))
link.save

或者:

Visit.create(:ip => get_remote_ip(env), :visit => visit)

答案 2 :(得分:0)

问题不在于Link没有访问属性。 问题是你的行

Link.first(:identifier => params[:short_url])

正在返回nil。

所以它没有找到任何符合您搜索条件的记录。

要证明这一点,请尝试

link = Link.get(1)

你应该找到一个结果。