Pergunta

Estou gostando Rails (mesmo que eu sou geralmente inquieto), e eu gosto de Ruby sendo muito OO. Ainda assim, a tendência de fazer enormes subclasses ActiveRecord e controladores enormes é bastante natural (mesmo se você usar um controlador por recurso). Se você fosse criar mais profundos mundos objeto, onde você iria colocar as classes (e os módulos, suponho)? Eu estou perguntando sobre visualizações (nos Ajudantes-se?), Controladores e modelos.

Lib está bem, e eu encontrei algumas soluções para obtê-lo para recarregar em um ambiente de dev , mas eu gostaria de saber se há uma maneira melhor de fazer essas coisas. Estou realmente apenas preocupados com as classes de crescimento muito grande. Além disso, o que acontece com os motores e como eles se encaixam?

Foi útil?

Solução

Porque Rails fornece a estrutura em termos de MVC, é natural que acabam usando única os recipientes modelo, Vista e Controlador que são fornecidos para você. A linguagem típica para iniciantes (e mesmo alguns programadores intermediários) é empinar toda a lógica no aplicativo no modelo (classe de banco de dados), controlador, ou exibição.

Em algum momento, tudo o que alguém aponta o "-modelo gordo, magro-controller" paradigma e desenvolvedores intermediários às pressas especial sobre o consumo de seus controladores e jogá-lo no modelo, que começa a se tornar uma nova lata de lixo para a lógica de aplicação.

controladores magros são, de fato, uma boa idéia, mas o corolário -. Colocar tudo no modelo, não é realmente o melhor plano

Em Ruby, você tem um par de boas opções para tornar as coisas mais modular. Uma resposta bastante popular é a de módulos apenas usar (geralmente escondidos em lib) que os grupos apossar de métodos, e depois incluir os módulos para as classes apropriadas. Isso ajuda em casos onde você tem categorias de funcionalidade que você deseja reutilização em várias classes, mas onde a funcionalidade ainda está teoricamente ligado às classes.

Lembre-se, quando você incluir um módulo em uma classe, os métodos tornam-se métodos de instância da classe, assim você ainda acabar com uma classe que contém um tonelada de métodos, eles estão apenas organizou bem em vários arquivos.

Esta solução pode funcionar bem em alguns casos - em outros casos, você vai querer pensar sobre o uso de classes em seu código que são não modelos, visualizações ou controladores.

Uma boa maneira de pensar sobre isso é o "princípio da responsabilidade única", que diz que uma classe deve ser responsável por um único (ou pequeno número) das coisas. Seus modelos são responsáveis ??pela persistência de dados de seu aplicativo para o banco de dados. Seus controladores são responsáveis ??por receber um pedido e retornar uma resposta viável.

Se você tem conceitos que não se encaixam perfeitamente em essas caixas (persistência, pedido / resposta de gestão), você provavelmente vai querer pensar sobre como você seria modelar a idéia em questão. Você pode armazenar classes não-modelo em app / aulas, ou em qualquer outro lugar, e adicionar esse diretório ao seu caminho de carga fazendo:

config.load_paths << File.join(Rails.root, "app", "classes")

Se você estiver usando passageiro ou JRuby, você provavelmente também quer adicionar seu caminho para os caminhos de carga ansiosos:

config.eager_load_paths << File.join(Rails.root, "app", "classes")

O bottom-line é que uma vez que você chegar a um ponto em Rails onde você se encontra fazendo esta pergunta, é hora para reforçar suas costeletas Ruby e começar a modelar classes que não são apenas as classes MVC que Rails dá por padrão.

Update: Esta resposta se aplica a Rails 2.x e superior

.

Outras dicas

Atualizar : O uso de preocupações foram confirmado como o novo padrão no Rails 4 .

É realmente depende da natureza do próprio módulo. Eu costumo colocar extensões controlador / modelo em um / preocupações pasta dentro do aplicativo.

# concerns/authentication.rb
module Authentication
  ...
end    

# controllers/application_controller.rb
class ApplicationController
  include Authentication
end



# concerns/configurable.rb
module Configurable
  ...
end    

class Model 
  include Indexable
end 

# controllers/foo_controller.rb
class FooController < ApplicationController
  include Indexable
end

# controllers/bar_controller.rb
class BarController < ApplicationController
  include Indexable
end

/ lib é a minha escolha preferida para bibliotecas de uso geral. Eu sempre tenho um namespace projeto em lib onde eu colocar todas as bibliotecas específicas da aplicação.

/lib/myapp.rb
module MyApp
  VERSION = ...
end

/lib/myapp/CacheKey.rb
/lib/myapp/somecustomlib.rb

Ruby / Rails extensões centrais ocorrem geralmente em inicializadores de configuração para que as bibliotecas são carregados apenas uma vez on Rails boostrap.

/config/initializer/config.rb
/config/initializer/core_ext/string.rb
/config/initializer/core_ext/array.rb

Para fragmentos de código reutilizáveis, muitas vezes eu criar (micro) plugins para que eu possa reutilizá-los em outros projetos.

Helper arquivos geralmente detém métodos auxiliares e às vezes as classes quando o objeto se destina a ser utilizado por auxiliares (por exemplo formulário Builders).

Esta é uma visão muito geral. Por favor, forneça mais detalhes sobre exemplos específicos, se você quiser obter sugestões mais personalizados. :)

... a tendência a fazer enorme subclasses activerecord e enorme controladores é muito natural ...

"enorme" é uma palavra preocupante ...; -)

Como são seus controladores se tornando enorme? Isso é algo que você deve olhar para: idealmente, controladores deve ser fina. Escolher uma regra de polegar fora do ar, eu sugiro que se você tem regularmente mais do que, digamos, 5 ou 6 linhas de código por método de controlador (ação), em seguida, seus controladores são provavelmente muito gordo. Há duplicação que poderiam mudar para uma função auxiliar ou um filtro? Existe lógica de negócios que poderia ser empurrado para baixo nos modelos?

Como seus modelos chegar a ser enorme? Você deve estar procurando maneiras de reduzir o número de responsabilidades em cada classe? Existem quaisquer comportamentos comuns que você pode extrair em mixins? Ou áreas de funcionalidade que você pode delegar a classes auxiliares?

EDIT: Tentando expandir um pouco, espero que não distorcer nada muito mal ...

Auxiliares: Live in app/helpers e são usados ??principalmente para fazer vistas mais simples. Eles estão ou específica controlador-(também disponível para todos os pontos de vista para que o controlador) ou geralmente disponível (module ApplicationHelper em application_helper.rb).

Filtros: Digamos que você tenha a mesma linha de código em diversas ações (muitas vezes, a recuperação de um objeto usando params[:id] ou similar). Que a duplicação pode ser abstraída primeiro a um método separado e depois para fora das ações inteiramente declarando um filtro na definição de classe, tais como before_filter :get_object. Veja a Seção 6 em Guia do ActionController Rails Vamos programação declarativa ser seu amigo.

refatoração modelos é um pouco mais de uma coisa religiosa. Discípulos de Tio Bob irá sugerir, por exemplo, que você siga as cinco mandamentos de SOLID . Joel & Jeff pode recomendar uma abordagem mais, er, "pragmático", embora eles não parecem ser um pouco mais reconciliado posteriormente. Encontrar um ou mais métodos dentro de uma classe que operam em um subconjunto bem definido de seus atributos é uma maneira de tentar aulas de identificação que pode ser reformulado para fora do seu modelo de ActiveRecord-derivada.

Trilhos modelos não precisam ser subclasses de ActiveRecord :: Base, pelo caminho. Ou, dito de outra forma, um modelo não tem que ser um análogo de uma mesa, ou mesmo relacionado a qualquer coisa armazenada em tudo. Ainda melhor, desde que o nome do seu arquivo em app/models acordo com as convenções do Rails (#underscore chamada no nome da classe para descobrir o que o Rails irá procurar), Rails vai encontrá-lo sem quaisquer requires sendo necessário.

Aqui está um excelente blog post sobre refatoração os modelos de gordura que parecem surgir a partir da filosofia "controlador fina":

http: / /blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

mensagem básica é "Não Extrato Mixins da gordura Models", classes de serviço utilização em vez disso, o autor fornece 7 padrões de fazê-lo

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top