Railsモデルでは、プロジェクト名の配列を返すクラスとメソッドを定義しています。ここで、私の質問は、ビューでProject.names配列を使用するのが正しいのか、それともコントローラーで配列を生成してインスタンス変数を渡すのが正しいのかということです。
class Project < ActiveRecord::Base
...snip...
def self.names
Project.select(:name).map {|x| x.name }
end
end
Railsモデルでは、プロジェクト名の配列を返すクラスとメソッドを定義しています。ここで、私の質問は、ビューでProject.names配列を使用するのが正しいのか、それともコントローラーで配列を生成してインスタンス変数を渡すのが正しいのかということです。
class Project < ActiveRecord::Base
...snip...
def self.names
Project.select(:name).map {|x| x.name }
end
end
私は間違いなくコントローラーのインスタンス変数を埋めるために固執します。ところで、あなたのコードについて一言:
Project.select(:name).map {|x| x.name }
次のようにリファクタリングできます。
Project.select(:name).map(&:name)
これは、次のようにリファクタリングできます。
Project.pluck(:name)
Rubyが大好きです。
一般に、データのプルとデータの表示を適切に分離することがベストプラクティスと見なされます。この場合、ビューはそのデータの表示のみを担当します。コントローラーで配列を生成し、それをビューに渡す方が確実に良いと思います。
MVCは非常に大きなトピックです。詳細については、Railsガイドをご覧ください:http://guides.rubyonrails.org/getting_started.html
実用的な観点から、ビューレイヤーとコントローラーロジックの間に線を引く場所は常に難しい決定です。コントローラに次のようなものを入力するのは疑わしいかもしれません。
# controller
@project_names = Project.names
# view
<%= @project_names.join(", ") %>
ビューでのみ使用し@procject_names
ます。
ただし、そのコードをビューから除外すると、後でビューを変更せずにこれを実行する機会が得られます。
# Controller is updated
@project_names = Project.names
# Show only matching projects
if params[:search]
@project_names = @project_names.select{|n| n =~ /#{params[:search]}/}
end
# view - still the same
<%= @project_names.join(", ") %>
また、MVVMパターンのDecoratorパターンとViewModelに基づいて構築された Drapergemも見てください。
Draperを使用すると、同じビューコードを使用して出力をレンダリングしながら、コントローラーをよりクリーンに保ち、必要に応じて同じオブジェクトに複数のデコレーターを設定できます(たとえば、Web用に1つ、メーラー用に1つ)。
デコレータに配置する一般的なものは、ログインしているユーザーに依存するローカライズされた日付であるため、ビューに収まりませんが、ビューレイヤーロジックでコントローラーが乱雑になります。