2

这个问题显然是微不足道的,但我是 Rails 的新手,我不知道我哪里弄错了。我正在从旧电子表格中填充相关模型。下面是一个 rake 导入任务片段。不知何故,当位置(华盛顿)相同并且已存在于 Smith 帖子的数据库中时,为第二条记录所做的新分配post.locations << location会删除与 Jones 帖子的位置关联。我的想法是将同一个位置与两个人的帖子相关联。我错过了什么?

导入.rake

data = [
  { name: 'Jones',
    post: 'President',
    city: 'Washington'
  },
  { name: 'Smith',
    post: 'Vice-President',
    city: 'Washington'
  },
  { name: 'Peters',
    post: 'Janitor',
    city: 'New York'
  }
]

data.each do |row|
  name = row[:name]; post = row[:post]; city = row[:city]
  person = Person.where(name: name).first_or_create
  post = Post.where(post: post).first_or_create
  location = Location.where(city: city).first_or_create
  post.people << person
  post.locations << location
  location.save; person.save; post.save
end

上面的导入导致

person1 = Person.find_by_name("Jones");
person1.posts.first.locations.first == nil
person2 = Person.find_by_name("Smith");
person2.posts.first.locations.first.city == "Washington"
person3 = Person.find_by_name("Peters");
person3.posts.first.locations.first.city == "New York"

位置.rb

class Location < ActiveRecord::Base
  belongs_to :post
  attr_accessible :city
end

人.rb

class Person < ActiveRecord::Base
  attr_accessible :name
  has_many :occupations
  has_many :posts, through: :occupations
end

post.rb

class Post < ActiveRecord::Base
  attr_accessible :post
  has_many :occupations
  has_many :people, through: :occupations
  has_many :locations
end

职业.rb

class Occupation < ActiveRecord::Base
  belongs_to :person
  belongs_to :post
  attr_accessible :person_id, :post_id, :since, :till
end
4

1 回答 1

1

好的,如果我正确理解您的模型,那么我认为这就是问题所在...

Location您在(many) 和Post(one)之间存在一对多关联。当您说post.locations << location时,Rails 正在做的是找到location并更新它post_id,因此覆盖您之前拥有的任何内容。您可能想要的是多对多,这样一个帖子可以有多个位置,反之亦然。

有两种设置方法:has_and_belongs_to_manyhas_many :through。后者通常更好,因为它更灵活,但现在我只展示更简单的方法:

class Post
  has_and_belongs_to_many :locations
end

class Location
  has_and_belongs_to_many :posts
end

create_table :posts_locations, :id => false do |t|
  t.integer :post_id
  t.integer :location_id
end

当您执行类似post.locations << location或的操作时,连接表会自动更新为将 Post 与 Location 相关联的 ID 对location.posts << post

于 2012-10-01T09:49:57.323 回答