2

学習演習として短縮 URL を作成しています。Visit モデル (この質問では重要ではありません) に加えて、Url モデルと Link モデルがあり、これらを関連付けて結合しています。Url クラスは Link に属し、Link クラスには :url が含まれています。

つまり、Link クラスで短縮メソッドを (Url コントローラーの create メソッドから) 呼び出すと、このエラー メッセージが表示されるという問題があります。

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

アプリケーション トレースは、Link クラスの「shorten」メソッドでこの行を指しています (以下にコピー)。

return url.link if url 

したがって、このエラーは、「url」で「link」を呼び出すことができないことを意味していると理解しています。しかし、私が作った協会がそうさせてくれるだろうと思いました。私が間違っていることを説明できますか

関連コード

新しいフォーム

<%= 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
4

3 に答える 3

1

@url作成されるLink.shorten前にに渡されます。したがってlink、nilオブジェクトでメソッドを呼び出しています。

@url.save動作させたい場合は、後に配置する必要があります。

于 2012-09-11T04:11:58.923 に答える
1

メソッドでオブジェクトを作成していますが、まだデータベースに何も保存していませUrl.new(params[:url])ん。メソッドの はデータベース内のテーブルを検索していますが、それでまだ URL が保存されていないため、テーブルが見つかりません。呼び出す前に保存する必要があります。createActiveRecordUrl.find_by_original(original)shortenurlsoriginalurlshorten

于 2012-09-11T04:15:49.907 に答える
0

@urlURL 文字列を渡すLink.shorten代わりに を渡し、フィールドに一致さoriginalせることで既存の URL を見つけようとします。それは、あなたが期待するのではなく、何らかの理由で返されます(理由はわかりません)。@url objectoriginalActiveRecord::Relationnil

ここでコードを変更する必要があると思います:

@link = Link.shorten(@url) 

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

@url保存された URL のみを探しているが、追加しようとしている新しい URL を探しているので、最初に保存する必要はないと思います。

于 2012-09-11T04:41:17.233 に答える