Ruby on rails Rails:按特定顺序创建属性

Ruby on rails Rails:按特定顺序创建属性,ruby-on-rails,activerecord,associations,Ruby On Rails,Activerecord,Associations,在我的Rails应用程序中,我有用户。要求用户提供其所在城市和地区/社区 class User < ActiveRecord::Base belongs_to :city belongs_to :district end class City < ActiveRecord::Base has_many :users has_many :districts end class District < ActiveRecord::Base has_many :

在我的Rails应用程序中,我有用户。要求用户提供其所在城市和地区/社区

class User < ActiveRecord::Base
  belongs_to :city
  belongs_to :district
end

class City < ActiveRecord::Base
  has_many :users
  has_many :districts
end

class District < ActiveRecord::Base
  has_many :users
  belongs_to :city
end
相反,我唯一能弄明白的是手动设置表单提交中的每个键,如:

@user.name = params[:user][:name] if params[:user][:name]
@user.city_name = params[:user][:city_name] if params[:user][:city_name]
@user.district_name = params[:user][:district_name] if params[:user][:district_name]
这种方法是可行的,但它是一种痛苦,有点脆弱,而且感觉完全错误,因为它开始用大量的逻辑来刺激控制器

我的问题是:

  • 是否有一种方法可以按照特定的顺序创建或更新属性(理想情况下是在模型中),以便控制器不必担心所有这些

  • 我做错了吗?如果是的话,什么方法会更好


  • 额外信息

    以下是我如何在用户模型上使用虚拟属性构建关联,以防与任何潜在回答者相关:

    我希望用户只需输入一个名字就可以选择一个城市,比如“伊利诺伊州芝加哥”。这很好,在用户模型上使用虚拟属性,如下所示:

    def city_name
      city.try :full_name
    end
    
    def city_name=(string)
      self.city = City.find_or_create_by_location_string( string )
    end
    
    对于用户来说,从他们选择的城市中查找或创建一个地区才有意义。其工作原理略有不同:

    def district_name
      district.try :name
    end
    
    def district_name=(string)
      if self.city.nil?
        raise "Cannot assign a district without first assigning a city."
      else
        self.district = self.city.districts.find_or_create_by_name( string )
      end
    end
    

    在模型层中,只要同时设置了城市名称和地区名称,地区协会就可以正常工作。

    我想你可以做一些事情来清理这个问题。首先,您可以使用委托来清理代码。e、 g

    delegate :name, :to => :city, :prefix => true, :allow_nil => true
    
    这样你就可以做像

    user = User.create
    user.city_name # nil
    city = City.create(:name => 'chicago')
    user.city = city
    user.save
    user.city_name # chicago
    
    它会起作用的


    接下来,我要说的是,从模型中去掉id逻辑的名称。您可以在表单(例如,ajax搜索将地区id/城市id放入隐藏字段)或控制器中执行此操作。然后,只需将城市/地区指定为正常

    我想你可以做一些事情来清理这个。首先,您可以使用委托来清理代码。e、 g

    delegate :name, :to => :city, :prefix => true, :allow_nil => true
    
    这样你就可以做像

    user = User.create
    user.city_name # nil
    city = City.create(:name => 'chicago')
    user.city = city
    user.save
    user.city_name # chicago
    
    它会起作用的


    接下来,我要说的是,从模型中去掉id逻辑的名称。您可以在表单(例如,ajax搜索将地区id/城市id放入隐藏字段)或控制器中执行此操作。然后,只需将城市/地区指定为正常

    这是个好主意。我能够基于使用ID的隐藏字段而不是将字符串传递给模型的想法来修改我的设置,这使得它变得简单多了。谢谢你的建议,你让我走上了正确的轨道。这解决了用户的问题,但没有回答问题,即是否可以按特定顺序保存属性…这是一个好主意。我能够基于使用ID的隐藏字段而不是将字符串传递给模型的想法来修改我的设置,这使得它变得简单多了。谢谢你的建议,你让我走上了正确的轨道。这解决了用户的问题,但没有回答问题,即是否可以按特定顺序保存属性。。。