2012-09-11 75 views
2

我在做一個網址縮短器作爲學習練習。除了訪問模式(對於這個問題不重要),它還有一個Url和一個Link模型,我已經加入了這些模型。 Url類屬於鏈接,Link類has_one:url。Rails:belongs_to和has_one關聯創建的方法

總之,問題是,當我稱之爲Link類的方法縮短(從創建在URL控制器方法),我收到此錯誤信息

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

應用程序跟蹤點這條線在連接類中的「縮短」的方法(下面複製)

return url.link if 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 

URL類

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 

回答

1

你傳入@urlLink.shorten其創建之前。所以你在一個零對象上調用link方法。

如果您希望它工作,您需要將它放在@url.save之後。

1

您的Url.new(params[:url])create方法正在創建一個ActiveRecord對象,但不保存任何內容到數據庫中。 shorten方法中的Url.find_by_original(original)正在搜索數據庫中的urls表,但由於未使用該original保存網址,因此無法找到該表。在呼叫shorten之前,您需要保存url

0

你傳入@urlLink.shorten而不是傳遞original URL字符串,並嘗試通過匹配@url objectoriginal領域找到一個現有的URL。由於某些原因(我不知道爲什麼)返回ActiveRecord::Relation,而不是您期望的nil

我想你應該在此更改代碼:

@link = Link.shorten(@url) 

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

我不認爲你必須拯救@url首先是因爲你正在尋找只存儲URL,但新一你要添加。