390

Thing という Rails モデルがあるとします。Thing には、オプションでインターネット上のどこかの URL に設定できる url 属性があります。ビュー コードでは、次のことを行うロジックが必要です。

<% if thing.url.blank? %>
<%= link_to('Text', thing_path(thing)) %>
<% else %>
<%= link_to('Text', thing.url) %>
<% end %>

ビューのこの条件付きロジックは醜いです。もちろん、ビューを次のように変更するヘルパー関数を作成することもできます。

<%= thing_link('Text', thing) %>

これで冗長性の問題は解決しますが、モデル自体に機能を持たせたいと思います。その場合、ビュー コードは次のようになります。

<%= link_to('Text', thing.link) %>

これには、明らかに、モデルに link メソッドが必要です。含める必要があるものは次のとおりです。

def link
  (self.url.blank?) ? thing_path(self) : self.url
end

問題の点では、thing_path() は Model コード内の未定義のメソッドです。いくつかのヘルパー メソッドをモデルに「取り込む」ことは可能だと思いますが、どのようにすればよいのでしょうか? また、ルーティングがアプリのコントローラー レイヤーとビュー レイヤーでのみ機能する本当の理由はありますか? モデル コードで URL を処理する必要がある場合 (外部システムとの統合など) はたくさん考えられます。

4

7 に答える 7

727

Rails 3 以降の場合:

Rails.application.routes.url_helpers

例えば

Rails.application.routes.url_helpers.posts_path
Rails.application.routes.url_helpers.posts_url(:host => "example.com")
于 2011-03-28T07:56:56.247 に答える
190

これを自分で行う方法に関する答えを見つけました。モデル コード内に次のように記述します。

Rails <= 2 の場合:

include ActionController::UrlWriter

Rails 3 の場合:

include Rails.application.routes.url_helpers

これは魔法のようthing_path(self)に、現在のものの URL を返したり、other_model_path(self.association_to_other_model)他の URL を返したりします。

于 2008-12-04T16:42:11.353 に答える
130

すべてのメソッドを含めるよりも、次のアプローチの方がクリーンであることがわかる場合もあります。

class Thing
  delegate :url_helpers, to: 'Rails.application.routes' 

  def url
    url_helpers.thing_path(self)
  end
end
于 2011-08-24T00:24:30.323 に答える
14

モデル内のメソッドは厳密にデータを処理するためのものであるため、ビューに表示されるものに関係するロジックはヘルパー メソッドに委譲する必要があります。

これがあなたができることです:

# In the helper...

def link_to_thing(text, thing)
  (thing.url?) ? link_to(text, thing_path(thing)) : link_to(text, thing.url)
end

# In the view...

<%= link_to_thing("text", @thing) %>
于 2008-12-04T16:14:47.587 に答える
1

そのようなロジックをモデルから除外する傾向がある方法があるかもしれませんが. それをビューに入れるべきではないことに同意します(スキニーのままにしてください)が、モデルがURLをデータの一部としてコントローラーに返さない限り、ルーティングはコントローラーにある必要があります。

于 2008-12-04T16:15:08.413 に答える
0

(編集:以前のせせらぎは忘れてください...)

わかりました、モデルまたは他の URL に移動する状況があるかもしれません...しかし、これがモデルに属しているとは本当に思いません。ビュー (またはモデル) の方が適切に聞こえます。

ルートについては、私が知る限り、ルートは直接ビューではなく、コントローラーのアクション (通常は「魔法のように」ビューを使用します) 用です。コントローラーはすべてのリクエストを処理し、ビューは結果を表示し、モデルはデータを処理してビューまたはコントローラーに提供する必要があります。ここで多くの人がモデルへのルートについて話しているのを聞いたことがありますが (私はほとんどそれを信じ始めています)、私が理解しているように、ルートはコントローラーに行きます。もちろん、多くのコントローラは 1 つのモデルのコントローラであり、よく呼び出されます<modelname>sController(たとえば、"UsersController" はモデル "User" のコントローラです)。

ビューに厄介な量のロジックを書いていることに気付いた場合は、ロジックをより適切な場所に移動してみてください。リクエストと内部通信ロジックはおそらくコントローラーに属し、データ関連のロジックはモデルに配置できますが(リンクタグなどを含む表示ロジックは含まれません)、純粋に表示関連のロジックはヘルパーに配置されます。

于 2008-12-04T16:15:28.973 に答える