为具有多态关系的模型设计控制器

时间:2013-03-29 23:01:26

标签: ruby-on-rails ruby devise polymorphism

TL; DR:

Devise :: RegistrationsController没有实例化相关的多态模型,解决这个问题的最佳方法是什么?

设置:

我有一个地址模型,我与不同的实体(例如一个人,一个企业)关联,因此使用多态关系:

class Person < ActiveRecord::Base
    has_one :address, :as => :addressable
    accepts_nested_attributes_for :address # to make fields_for work
end

class Address < ActiveRecord::Base
    belongs_to :addressable, :polymorphic => true
end

我使用了Person模型作为Devise模型,但遇到了在注册新帐户时未实例化或保存Address对象的问题。

据我所知,Person控制器被Devise RegistrationController取代(路由:new_person_registration GET /person/sign_up(.:format) devise/registrations#new),在我开始使用Devise之前,有代码来实例化那些用来做技巧的对象:

class PeopleController < ApplicationController
    [...]
    def create
        @person = Person.new(params[:person])
        @person.address = Address.new(params[:address])
        [...some checking...]
        @person.save
        @person.address.save

    end
    def new
        @person = Person.new
        @person.address = Address.new
    end

end

现在看来,Devise :: RegistrationsController没有创建Address对象。

一个建议的解决方案是使用回调来初始化对象,因此我的人模型有:

before_create :instantiate_all
before_save :save_all

def save_all
    self.address.save
    self.save 
end

def instantiate_all
    if self.address.nil?
        self.address = Address.new
    end
end

我还是得到了

NoMethodError (undefined method `address' for nil:NilClass):
    app/models/person.rb:25:in `save_all'

我正在考虑覆盖RegistrationController,但似乎通过调用super,我将执行相应父方法的整个块,因此无法插入我想要的操作。

最后,覆盖控制器,复制代码并添加我的代码似乎太错误了,不能成为完成此操作的唯一方法。

我很感激你们这些人的想法。

0 个答案:

没有答案