2010-12-16 76 views
2

我有一个注册模型has_many:电话 注册模型accept_nested_attributes_for:电话,::reject_if数字和代码空白,并且具有attr_accessible:telephones_attributes(和所有其他字段)错误?我必须重新分配参数两次以更新has_many关联

电话belongs_to的:寄存器,并且具有attr_accessible所有字段

当窗体发送参数,可以它似乎是良好的,但是,当表单字段被发送到@ register.attributes =参数[:注册]它会更新所有的字段,但不会更新现有的电话(它们应该已经更新了它的字段),它们只是保持原来的样子(我检查了什么时候调试过g)

现在,这是它变得很奇怪,在控制台,当我测试它,我认为这是关于PARAMS,因为我可以使它在那里工作,现在我发现它的行为就像我想要的has_many只有在我第一次尝试分配它之后,我才在控制器(批量分配参数两次)中尝试这种方式,它工作正常。

当然,它必须与我正在使用model.attributes = params来分配的事实有关,我这样做,所以我也可以保存对系统变化的监视(和我' m不会在before_filters中这样做,因为我必须访问一些我认为特定于控制器的数据,比如current_user和on)可能是糟糕的设计......但这不是很奇怪吗?我必须为此分配两次工作?这是一种错误吗?有谁知道是否有办法解决它?

  • 我在铁轨2.3.8,1.8.6红宝石

编辑: 这里的示例代码,很多这样的代码这里是葡萄牙语,寿:/

telefone =电话, cadastro =注册

正如你可以看到我已经得到了聚集做一些改变协会的all_changes方法,那里有征求意见(comentario_interno /外路)的自定义设置器为手段,以增加对评论在时间...

#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]} 
+0

你能提供范例代码吗?您应该使用model.attributes = params来设置属性的方法。我的猜测是,你正在其他地方滑倒,无效或缺少属性。 – 2010-12-16 23:52:26

回答

0

在你的例子中不清楚如何使用all_changes或如果它甚至被称为。试着简化你的代码,看看这个问题实际上是用Rails还是用你的实现。例如,下面应该工作:

class Telefone < ActiveRecord::Base 
    belongs_to :cadastro 
    validates_presence_of :ddd 
    validates_presence_of :numero 
    validates_numericality_of :ddd 
    validates_numericality_of :numero 
end 

class Cadastro < ActiveRecord::Base 
    has_many :telefones 

    accepts_nested_attributes_for :telefones 
end 

@cadastro.attributes = {:telefones_attributes => [{:ddd => 111, :numero => 1234567}]} 
@cadastro.save 

你也应该注意到,您不需要reject_if条件在accepts_nested_attributes_for,因为你已经验证的存在:DDD和:NUMERO基类。

相关问题