2013-08-25 5 views
0

У меня есть экземпляр переменной @posts_by_month, определенный в двух контроллерах и используются в двух видах:Как разделить код между двумя контроллерами

Сообщения Контроллер:

class PostsController < ApplicationController 

def index 
    @posts = Post.all 
    @posts_by_month = Post.all.group_by { |post| post.created_at.strftime("%L") } 

    respond_to do |format| 
     format.html # index.html.erb 
     format.json { render json: @posts } 
    end 
    end 
. 
. 
end 

Архивы контроллер:

class ArchivesController < ApplicationController 
    def index 
    @posts_by_month = Post.all.group_by { |post| post.created_at.strftime("%B") } 
    end 
end 

Индексный индекс:

<h1>Listing posts</h1> 
. 
. 
. 
<div> 
    <% @posts_by_month.each do |millisecond, posts| %> 
    <p><%= millisecond %>milliseconds <%= posts.count %></p> 
    <% end %> 
</div> 

Archives посмотреть индекс:

<% @posts_by_month.each do |monthname, posts| %> 
<%= monthname %> 
<ul> 
    <% posts.each do |post| %> 
    <h3><%= post.title %></h3> 
    <p><%= post.body %></p> 
    <% end %> 
</ul> 
<% end %> 

У меня есть два вопроса. Есть ли способ определить переменную экземпляра @posts_by_month, чтобы я мог иметь это доступное обоим представлениям, не повторяя его в каждом соответствующем контроллере?

Во-вторых, существует ли способ, посредством которого миллисекундная часть <p><%= millisecond %>milliseconds <%= posts.count %></p> может быть переведена в ссылку, ведущую к просмотру архива?

Примечание: в моем приложении миллисекунда будет заменено на месяц, как в режиме архива.

ответ

2

Когда действие было выполнено, иначе, образец закончен. Нет больше переменной экземпляра.

Переменные экземпляра в представлении не являются реальными переменными экземпляра. View и Controller находятся в разных классах, как они могут совместно использовать экземпляр? Реальность такова, что Rails делает это, чтобы скопировать эту переменную экземпляра из экземпляра Controller, чтобы точно просмотреть экземпляр экземпляра.

Таким образом, ответ на ваш вопрос: Нет

Но вы все еще можете высушить свой код частного метода в контроллере приложения, чтобы поделиться с PostsController и ArchiveController.

class ApplicationController 
    private 
    def posts_by_time(arg) 
    Post.all.group_by { |post| post.created_at.strftime(arg) } 
    end 
end 

class PostsController < ApplicationController 
    def index 
    @posts = posts_by_time "%L" 
    # ... 
    end 
end 

class ArchievesController < ApplicationController 
    def index 
    @posts = posts_by_time "%B" 
    # ... 
    end 
end 
+0

У вас есть ссылка на то, где говорится, что состояние контроллера копируется для создания состояния представления? Я предпочел бы (и надеюсь), что состояние контроллера будет доступно через прокси-сервер в представлении, и нет ненужного копирования (если не сделать явно, например, заменяя шаблоны и т. Д.), – Domi

1

Да, вы можете уменьшить дублирование одной и той же переменной. Один из способов заключается в использовании фильтров:

Определение mthod внутри контроллеров приложений:

class ApplicationController < ActionController::Base 
    private 
    def find_post_by_month 
    @posts_by_month = Post.all.group_by { |post| post.created_at.strftime("%L") } 
    end 
end 

Тогда внутри архива и сообщений контроллеров:

class ArchivesController < ApplicationController 
    before_filter :find_post_by_month, :only => :index 
    ...  
end 


class PostsController < ApplicationController 
    before_filter :find_post_by_month, :only => :index 
    ... 
end 

Это даст вам дорожим в @posts_by_month переменной.

И, для изготовления связи упомянутого текста, вы должны использовать этот код:

<p><%= link_to "#{millisecond} milliseconds", path %></p> # Replace path with your url 
Смежные вопросы