Posts Tagged ‘active!’

Ruby on Rails ActiveRecord como excluir registros dependentes e arquivos anexados com o Paperclip

Postado em 10 jun 2009
Categoria(s) Ruby on Rails

Digamos que você tenha uma mensagem, e essa mensagem possa ter várias fotos e vídeos relacionadas com ela.

Com o model message.rb da forma abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Message < ActiveRecord::Base
  # associações
  belongs_to :user
  has_many :photos
  has_many :videos
 
  # validações
  # presença
  validates_presence_of :title
  validates_presence_of :content
 
  # tamanho máximo
  validates_length_of :title, :maximum => 255
end

Se você usar Paperclip para anexar as fotos e vídeos, quando você apagar uma mensagem os arquivos de fotos e vídeos iram continuar a existir no disco rígido.

Para forçar que todas as relações filhas sejam apagadas quando você excluir a mensagem, você deve adicionar :dependent => :destroy na declaração has_many, ficando assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Message < ActiveRecord::Base
  # associações
  belongs_to :user
  has_many :photos, :dependent => :destroy
  has_many :videos, :dependent => :destroy
 
  # validações
  # presença
  validates_presence_of :title
  validates_presence_of :content
 
  # tamanho máximo
  validates_length_of :title, :maximum => 255
end

Essa alteração força para que todos os dependentes sejam excluídos.

Se você gostou desse texto e acha que ajudou você, me recomende: Recommend Me.

  • Share/Bookmark

Ruby on Rails como resolver A copy of … has been removed from the module tree but is still active!

Postado em 26 mar 2009
Categoria(s) Ruby on Rails

Eu estou desenvolvendo um CMS em Ruby on Rails 2.3, um dos requisitos desse CMS é um alto grau de componentização em módulos.

Eu fiquei 1 semana pensando como poderia fazer isso da melhor forma no Rails, foi ae que eu descobri o Rails Engines no Rails 2.3, eu percebi que através dele eu conseguiria dividir a minha aplicação em módulos.

O Rails Engines permite embutir uma aplicação dentro da outra, para você entender melhor veja esse Railscasts: http://railscasts.com/episodes/149-rails-engines e http://rails-engines.org.

Eu consegui embutir uma aplicação dentro da outra e modularizar o funcionamento do meu CMS.

Tudo estava funcionando lindo e maravilhosamente na primeira requisição a página, por exemplo: http://localhost:3000/admin/node_types mas quando eu fiz a segunda requisição me deparei com essa mensagem de erro:

A copy of BackendController has been removed from the module tree but is still active!

E depois disso a página parou de funcionar e só aparecia essa mensagem de erro, fui atrás para descobrir o que era.

Pelo o que eu entendi o Rails carrega o conteúdo do plugin uma vez só, e depois faz o descarregamento das classes da memória, na segunda vez que você tenta acessar a classe ela não está mais na memória e dá problema.

No meu caso é a classe BackendController herdada pelo controlador do plugin Admin::NodeTypesController.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
class Admin::NodeTypesController < BackendController
 
  # GET /admin/node_types
  # GET /admin/node_types.xml
  def index
    @node_types = NodeType.all
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render : xml => @node_types }
    end
  end
 
  # GET /admin/node_types/1
  # GET /admin/node_types/1.xml
  def show
    @node_type = NodeType.find(params[:id])
 
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render : xml => @node_type }
    end
  end
 
  # GET /admin/node_types/new
  # GET /admin/node_types/new.xml
  def new
    @node_type = NodeType.new
 
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render : xml => @node_type }
    end
  end
 
  # GET /admin/node_types/1/edit
  def edit
    @node_type = NodeType.find(params[:id])
  end
 
  # POST /admin/node_types
  # POST /admin/node_types.xml
  def create
    @node_type = NodeType.new(params[:node_type])
 
    respond_to do |format|
      if @node_type.save
        flash[:notice] = 'Criado com sucesso.'
        format.html { redirect_to([:admin, @node_type]) }
        format.xml  { render : xml => @node_type, :status => :created, :location => @node_type }
      else
        format.html { render :action => "new" }
        format.xml  { render : xml => @node_type.errors, :status => :unprocessable_entity }
      end
    end
  end
 
  # PUT /admin/node_types/1
  # PUT /admin/node_types/1.xml
  def update
    @node_type = NodeType.find(params[:id])
 
    respond_to do |format|
      if @node_type.update_attributes(params[:node_type])
        flash[:notice] = 'Atualizado com sucesso.'
        format.html { redirect_to([:admin, @node_type]) }
        format.xml  { head : ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render : xml => @node_type.errors, :status => :unprocessable_entity }
      end
    end
  end
 
  # DELETE /admin/node_types/1
  # DELETE /admin/node_types/1.xml
  def destroy
    @node_type = NodeType.find(params[:id])
    @node_type.destroy
 
    respond_to do |format|
      format.html { redirect_to(admin_node_types_url) }
      format.xml  { head : ok }
    end
  end
end

Eu descobri duas soluções para resolver esse problema:

A primeira é fazer em que toda a requisição ao controlador Admin::NodeTypesController a classe BackendController será recarregada novamente adicionado load ‘backend_controller.rb’:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
load 'backend_controller.rb'
 
class Admin::NodeTypesController < BackendController
 
  # GET /admin/node_types
  # GET /admin/node_types.xml
  def index
    @node_types = NodeType.all
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render : xml => @node_types }
    end
  end
 
...

A segunda forma é dizer que a classe não deve ser descarregada, adicionando unloadable dentro da classe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Admin::NodeTypesController < BackendController
  unloadable
 
  # GET /admin/node_types
  # GET /admin/node_types.xml
  def index
    @node_types = NodeType.all
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render : xml => @node_types }
    end
  end
 
...

Essas soluções eu encontrei nos seguintes links:

Obs.: Eu coloquei um espaço onde aparece : xml, entre o : e xml, tive que fazer isso senão o wordpress fica adicionado imagens de smily no meio do código. Mesma coisa para : ok. erggg

Se você gostou desse texto e acha que ajudou você, me recomende: Recommend Me.

  • Share/Bookmark