2

会社を作成し、その過程で従業員になるユーザーがいます。employees テーブルには:user_idと があり:company_idます。

class User
has_many :employees
has_many :companies, :through => :employees

class Employee
belongs_to :user
belongs_to :company
attr_accessible :active

class Company
has_many :employees
has_many :users, :through => employees

かなり基本的です。リソース EMPLOYEE には、 boolean などの外部キー以外の属性があります:active。を使用したいのですattr_accessibleが、これはいくつかの問題を引き起こします。属性:user_idは正しく設定されていますが、:company_idnil です。

@user.companies << Company.new(...)
Employee id:1 user_id:1 company_id:nil

だから私の質問は次のとおりです。:user_idが正しく設定されている場合、そうではないにもかかわらず、同じように正しく設定されないのattr_accessibleはなぜですか? :company_idであってはなりませんattr_accessible

Rails 3.0.8 を使用しており、3.0.7 でもテストしました。

4

2 に答える 2

2

ここではたくさんのビットが一緒に働いています。

あなたは間違いなくすべてのモデルでattr_accessibleを使用したいと思います。(Googleの「Railsの一括割り当てをハック」し、一括割り当てに関するRailsガイドをお読みください。)

モデルにattr_accessibleを追加すると、明示的に許可したものを除いて、ハッシュからのすべての割り当て(一括割り当て)が無効になります。ただし、一度に1つずつ直接値を割り当てることはできます。

外部キーは一括割り当てから除外するのが良いように思われるので、attr_accessibleにリストしないでください。

.createメソッドと.buildメソッドは一括割り当てを使用していないため、 1つの外部キーの関連付けの値を設定できます。複数の関連付けがある場合は、私が知る限り、最初の関連付けを除くすべてを個別に設定する必要があります。

最後に、外部キーの実際のIDは、ActiveRecordではなくデータベースによって作成されます。したがって、親レコードと子レコードを同時に作成するか、親に外部キーを割り当てる前に、最初に子を保存する必要があります。それ以外の場合、割り当てに使用できるIDはありません。

あなたの例から、従業員がどのようにインスタンス化されているのかはわかりません。しかし、従業員はユーザーと会社の両方に属しているので、@ userがすでに存在すると仮定すると、このようなものが機能する可能性があると思います。

company  = @user.companies.create(..) # fills in company.user_id and saves to DB
employee = @user.employees.build(..)  # fills in employee.user_id but does NOT save yet
employee.company = company            # fills in employee.company_id
employee.save                         # now save to DB
于 2012-03-28T23:25:39.093 に答える
0

company_id は単純に、Company がまだデータベースに保存されていないため、nil です。Company.new は、まだ保存せずにメモリ内にオブジェクトを作成するだけです。

もしあなたがそうするなら:

@user.companies << Company.create(..)

また

@user.companies << Company.first

どちらも機能するはずです。私もうまくいくはずだと思うより短い方法さえあります:

@user.companies.create(..)

それはすべて、関連付けを保存する時点によって異なります。場合によっては、employee モデルと company モデルをすぐに保存せず、代わりに親モデル (User) が保存されるまで待つ方がよい場合があります。その場合、次を使用できます。

@user.companies.build(..) 

(これはあなたの例のコードに似ています)。

Employee モデルのブール属性に関してはactive、これがデータベースの列である場合、明示的に宣言する必要はありませんattr_accessible。デフォルトでアクセス可能になります。

于 2011-06-22T09:59:00.440 に答える