2

我正在制作一个网址缩短器作为学习练习。除了访问模型(这对于这个问题并不重要)之外,它还有一个 Url 和一个 Link 模型,我已经加入了关联。Url 类属于 Link,Link 类有_one :url。

简而言之,问题是当我在 Link 类中调用 short 方法(来自 Url 控制器中的 create 方法)时,我收到此错误消息

undefined method `link' for #<ActiveRecord::Relation:0x00000102f648b8>

应用程序跟踪指向 Link 类的“缩短”方法中的这一行(复制如下)

return url.link if url 

所以,我理解这个错误意味着我不能在“url”上调用“链接”。但是,我认为我创建的关联将允许我这样做。你能解释一下我做错了什么吗

相关代码

新形式

<%= simple_form_for @url do |f| %>
  <%= f.input :original,  :label => 'Original Link', :input_html => { :maxlength => 70 } %>
  <%#= f.input :custom,  :label => '(Optional) Create your own custom shortened link ' %>
  <%= f.button :submit %>
<% end %>

创建方法url控制器

def create
    @url = Url.new(params[:url])
    @link = Link.shorten(@url) 

    respond_to do |format|
      if @url.save
        format.html { redirect_to action: "index", notice: 'Url was successfully created.' }
        format.json { render json: @url, status: :created, location: @url }
      else
        format.html { render action: "new" }
        format.json { render json: @url.errors, status: :unprocessable_entity }
      end
    end

  end

网址类

class Url < ActiveRecord::Base
  attr_accessible :original

  belongs_to :link
end

用缩短方法链接类

class Link < ActiveRecord::Base
  attr_accessible :identifier
  has_one :url
  has_many :visits


  def self.shorten(original, custom=nil)
    url = Url.find_by_original(original) 

    return url.link if url        #this is the problem line
    link = nil
    if custom
      raise 'Someone has already taken this custom URL, sorry' unless Link.find(:identifier => custom).nil?  #this  Link.find
      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
4

3 回答 3

1

你在它被创建之前传递@url给它。Link.shorten所以你link在一个 nil 对象上调用该方法。

@url.save如果你想让它工作,你需要把它放在后面。

于 2012-09-11T04:11:58.923 回答
1

Url.new(params[:url])create方法中正在创建一个ActiveRecord对象,但尚未将任何内容保存到数据库中。Url.find_by_original(original)方法中的方法shorten是在数据库中搜索urls表,但找不到,因为还没有保存 url original。您需要url在调用它之前保存shorten它。

于 2012-09-11T04:15:49.907 回答
0

您正在传递@urltoLink.shorten而不是传递URL 字符串,并尝试通过匹配到字段original来查找现有 URL 。由于某种原因返回(我不知道为什么),而不是你所期望的。@url objectoriginalActiveRecord::Relationnil

我认为您应该在这里更改代码:

@link = Link.shorten(@url) 

@link = Link.shorten(@url.original) 

我认为您不必先保存@url,因为您只查找存储的 URL,而是要添加的新 URL。

于 2012-09-11T04:41:17.233 回答