0

我有两个模型:User如下Location

class User < ActiveRecord::Base
  attr_accessible :location, :password, :user_name, :password_confirmation

  validates :location, :user_name, :presence => true
  validates :password, :presence => true, :confirmation => true

  has_one :location, :foreign_key => 'location'

end

class Location < ActiveRecord::Base
  attr_accessible :loc_id, :loc_name

  belongs_to :user, :foreign_key => 'loc_id'
end

您可以看到我为模型使用了自定义的 foreign_key。我使用表单生成器来构建用户注册表单,但是当我提交数据时出现错误:

Location(#2170327880) expected, got String

simple_form用来构建表单,相关代码是:

= f.input :location, :collection => Location.all.collect {|c| [c.loc_name, c.loc_id]}

我该如何解决这个问题?location_id或者我必须像关联一样使用默认的 foreign_key吗?

谢谢。

更新:

当我将模型中的location字段重命名为并删除这样的:Userloc_id:foreign_key

class User < ActiveRecord::Base
  attr_accessible :loc_id, :password, :user_name, :password_confirmation

  validates :loc_id, :user_name, :presence => true
  validates :password, :presence => true, :confirmation => true

  has_one :location, :foreign_key => 'location'

end

class Location < ActiveRecord::Base
  attr_accessible :loc_id, :loc_name

  belongs_to :user
end

它工作正常。但我仍然想知道如何关联UserLocation模型。

PS我使用Location模型来存储国家代码和国家名称,永远不会更新User

4

4 回答 4

1

听起来你真的想要

class User < ActiveRecord::Base
  belongs_to :location
end

class Location < ActiveRecord::Base
  has_many :users
end

这意味着用户有一个location_id列。如果您以其他方式执行操作(位置上的 user_id 列),则给定位置只能与一个用户相关联。rails 方式是location_id用户在位置表中的 id 列上“点”。如果您希望它指向不同的列,请使用该:primary_key选项(:foreign_key如果您希望用户列被称为 location_id 以外的其他名称,则该选项是)

就表单而言,你做不到f.select :location——表单不知道如何传递这样一个复杂的对象。在这些情况下,您要设置表单来控制 location_id 属性,即

= f.input :location_id, :collection => Location.all.collect {|c| [c.loc_name, c.id]}

如果您沿着让 location id 列引用 location 上的 loc_id 列的路线走下去,那么您需要将其更改为

= f.input :location_id, :collection => Location.all.collect {|c| [c.loc_name, c.loc_id]}

就个人而言,如果您只是刚开始使用 rails,我会坚持使用默认值

于 2012-06-09T12:27:05.437 回答
1

看起来你在滥用外键。在 User 模型中,您应该有 justhas_one :location并且 location 模型应该有 user_id 属性。在位置模型中,您只需要编写belongs_to :user. 外键始终是另一个(外部)表的索引。

于 2012-06-08T08:23:01.807 回答
0
class User < ActiveRecord::Base
  # stuff

  has_one :location    
end

class Location < ActiveRecord::Base
  # more stuff

  belongs_to :user
end
于 2012-06-08T08:30:17.940 回答
0

如果您最终想要选择具有相同位置的所有用户,您可能希望对模型进行一些不同的设置。现在,因为每个用户在位置表中都有自己的位置记录,所以您最终会得到重复的位置,并且您必须找到所有这些位置以获得唯一位置并从中提取 user_ids。

而是这样做

class User < ActiveRecord::Base
   has_one :placement
   has_one :location, through: :placement
end

class Placement < ActiveRecord::Base
    belongs_to :user
    belongs_to :location
end

class Location < ActiveRecord::Base
    has_many :placements
    has_many :users, through: :placements
end

. 至于迁移,Placement 应该有一个 :user_id 和 :location_id。您可以删除当前在 Location 中的 :user_id。这段代码的意思是我们有很多用户,我们有很多独特的位置,我们通过创建展示位置将用户放置在独特的位置,这表明具有 :user_id 的用户位于具有 :location_id 的位置。另外,不要忘记添加一行

add_index :placements, [:user_id, :location_id], unique: true

这样您就不能将用户多次放置在一个位置。

编辑:忘记添加:您可以通过简单地获取位置记录并调用 location.users 来获取某个位置的所有用户

于 2012-06-08T15:53:11.513 回答