2

この質問は明らかに些細なことですが、私はRailsの初心者であり、どこで間違っているのかわかりません。古いスプレッドシートから関連するモデルを作成しています。以下は、rakeインポートタスクスニペットです。どういうわけか、場所(ワシントン)が同じで、スミスの投稿のデータベースにすでに存在する場合、2番目のレコードに対して行われた新しい割り当てによりpost.locations << location、ジョーンズの投稿との場所の関連付けが削除されます。私のアイデアは、同じ場所を両方の人の投稿に関連付けることでした。私は何が欠けていますか?

import.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"

location.rb

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

person.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

occupation.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(多) とPost(1)の間に 1 対多の関連付けがあります。と言うとpost.locations << location、Rails が行っているのはそれを見つけてlocation更新することpost_idで、以前にあったものを上書きします。あなたがおそらく望むのは多対多であるため、投稿は複数の場所を持つことができ、その逆も可能です。

設定するにはhas_and_belongs_to_many、 、またはの 2 つの方法がありますhas_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 に答える