我有一个 Register 模型,它 has_many :telephones Register 模型接受_nested_attributes_for :telephones, :reject_if 号码和代码空白?,并且有 attr_accessible :telephones_attributes (以及所有其他字段)
电话belongs_to :register 并且所有字段都具有attr_accessible
当表单发送参数时,它似乎格式正确,但是当表单字段发送到 @register.attributes = params[:register] 时,它将更新所有字段,但不会更新现有电话(应该更新到它的字段也是如此),它们只是保持以前的样子(我在调试时检查过)
现在这是它变得奇怪的地方,在我测试它的控制台中,我认为它与参数有关,因为我可以让它在那里工作,现在我发现它的行为就像我想要的 has_many 关联只有在第一次之后我尝试分配它,我在控制器中尝试了这个(质量分配参数两次)并且它有效。
当然,它必须与我使用 model.attributes = params 分配的事实有关,我这样做是为了我还可以保存对系统更改的监视(而且我没有这样做在 before_filters 中,因为我必须访问一些我认为特定于控制器的数据,例如 current_user 和 on)可能是糟糕的设计......但这不是很奇怪吗?我必须批量分配两次才能工作?这是某种错误吗?有谁知道是否有办法解决它?
- 我在 Rails 2.3.8,红宝石 1.8.6
编辑:这是示例代码,这里的很多代码都是葡萄牙语,虽然:/
电话 = 电话,地籍 = 登记
正如你所看到的,我有一个 all_changes 方法来聚合对某些关联所做的更改,还有一个用于注释的自定义设置器(commentario_interno/externo)作为一次添加一条注释的方法......
#models
class Telefone < ActiveRecord::Base
#relações
belongs_to :cadastro
#validações
validates_presence_of :ddd
validates_presence_of :numero
validates_numericality_of :ddd
validates_numericality_of :numero
attr_accessible :ddd, :numero, :cadastro_id, :id
end
class Cadastro < ActiveRecord::Base
#relações
#cliente
belongs_to :estado
belongs_to :indicacao
has_many :telefones
has_one :outra_indicacao
#venda
belongs_to :user
belongs_to :banco
belongs_to :plano
belongs_to :pacote
belongs_to :situacao
belongs_to :situacao_diversa
has_many :comentario_internos
has_many :comentario_externos
#system
#has_many :sys_logs
has_many :sys_logs, :as => :monitorable
has_many :email_history, :through => :sys_logs, :conditions => {:type => 'SysEmail'} , :source => :sys_actions
has_many :lock_history, :through => :sys_logs, :conditions => {:type => 'SysLock'}, :source => :sys_actions
has_many :alteracao_history, :through => :sys_logs, :conditions => {:type => 'SysAlteracao'}, :source => :sys_actions
#filtros
#validações
#cliente
validates_presence_of :tipo, :nome, :cpfcnpj, :rg, :data_nascimento, :profissao, :filiacao, :email, :logradouro,
:tp_logradouro, :numero, :bairro, :cep, :cidade
validates_uniqueness_of :cpfcnpj
validates_presence_of :estado
#validate :must_have_at_least_one_telephone
#venda
validates_presence_of :user
validates_presence_of :situacao
validates_numericality_of :agencia, :allow_blank => true
validates_numericality_of :digito_agencia, :allow_blank => true
validates_numericality_of :cc, :allow_blank => true
validates_numericality_of :digito_cc, :allow_blank => true
validates_numericality_of :cpf_titular, :allow_blank => true
#cpf must be unique
accepts_nested_attributes_for :telefones, :reject_if => lambda {|attr| attr['ddd'].blank? && attr['numero'].blank?}
accepts_nested_attributes_for :outra_indicacao
accepts_nested_attributes_for :comentario_internos, :reject_if => lambda {|attr| attr['comentario'].blank?}
accepts_nested_attributes_for :comentario_externos, :reject_if => lambda {|attr| attr['comentario'].blank?}
#attr_accessible :new_comentario_interno, :new_comentario_externo, :telefones_attributes
attr_accessible :telefones_attributes, :new_comentario_interno, :new_comentario_externo, :outra_indicacao_attributes,
:user_id, :cc, :digito_cc, :data_instalacao, :cpfcnpj, :profissao, :tp_logradouro, :agencia, :cpf_titular,
:situacao_id, :estado_id, :plano_id, :banco_id, :nome, :data_nascimento, :cep, :observacao, :data_agendamento,
:dia_vencimento, :digito_agencia, :pacote_id, :nome_titular, :logradouro,
:indicacao_id, :telefones_attributes, :contrato, :confirmacao_condicoes, :estado_civil, :cidade,
:horario_retorno, :tipo, :sexo, :filiacao, :complemento, :bairro, :rg, :expeditor, :email, :numero,
:situacao_diversa_id
def new_comentario_interno=(attributes = {})
self.comentario_internos << ComentarioInterno.new(:user_id => attributes[:user_id], :comentario => attributes[:comentario]) unless attributes[:comentario].blank?
end
def new_comentario_externo=(attributes = {})
self.comentario_externos << ComentarioExterno.new(:user_id => attributes[:user_id], :comentario => attributes[:comentario]) unless attributes[:comentario].blank?
end
def self.buscar_cadastros(options = {})
conditions = []
conditions << sanitize_sql(["cadastros.situacao_id = ?", options[:situacao_id]]) unless options[:situacao_id].blank?
conditions << sanitize_sql(["cadastros.user_id = ?", options[:user_id]]) unless options[:user_id].blank?
conditions << sanitize_sql(["cadastros.created_at >= ? AND cadastros.created_at < ?",
Date.civil(options[:ano].to_i, options[:mes].to_i, 1),
Date.civil(options[:ano].to_i, options[:mes].to_i, -1)]) unless options[:ano].blank? || options[:mes].blank?
self.find(:all, :conditions => conditions.join(" AND "))
end
def self.vendas_count_on(situacao_id, options = {})
select = sanitize_sql(["SELECT count(*) FROM cadastros LEFT JOIN situacaos ON cadastros.situacao_id = situacaos.id
WHERE situacaos.id = ?", situacao_id])
select << sanitize_sql([" AND cadastros.user_id = ?", options[:user_id]]) unless options[:user_id].blank?
select << sanitize_sql([" AND cadastros.created_at >= ? AND cadastros.created_at < ?",
Date.civil(options[:ano].to_i, options[:mes].to_i, 1),
Date.civil(options[:ano].to_i, options[:mes].to_i, -1)]) unless options[:ano].blank? || options[:mes].blank?
count_by_sql(select)
end
def all_changes
#agregar telefones, outra indicacao, comentarios internos, comentarios externos
changes = self.changes
h = Hash.new
h["outra_indicacao"] = self.outra_indicacao.descricao_change if self.outra_indicacao && self.outra_indicacao.changed?
if self.id
old_telefones = connection.execute("select ddd || '-' || numero as numformat from telefones where cadastro_id = #{self.id}").collect {|t| t["numformat"]}
else
old_telefones = []
end
new_telefones = self.telefones.collect {|t| "#{t.ddd}-#{t.numero}"}
h["telefones"] = [old_telefones.join(', '), new_telefones.join(', ')] unless (old_telefones - new_telefones).empty?
changes.delete("syslogid")
changes.merge(h)
end
def locked?
#pegar o ultimo lock e retornar o valor
last_lock = self.lock_history.last
if last_lock
return last_lock.locked?
else
return false
end
end
end
#here's what Ive got to do in controller for this to work, remember its only when updating existing phones, creating is working normally
@cadastro.attributes = params[:cadastro]
@cadastro.attributes = {:telefones_attributes => params[:cadastro][:telefones_attributes]}