2013-05-22 17 views
27

私は在庫管理のためにRailsフロントエンドを書いています。私は、ユーザーが製品を登録することができるようにしたいので、私は持っている:オプションのレールはありませんbelongs_to

class User < ActiveRecord::Base 
    has_many :products 
    # <snip> 
end 

class Product < ActiveRecord::Base 
    belongs_to :user 
    # <snip> 
end 

問題は、製品が前にユーザが登録されることに作成されていることです。つまり、Product.createに電話し、user_idnilに設定するだけで十分です。あなたが想像できるように、しかし、Railsは箱から出して、これをサポートしていません:

> Product.create! 
    (0.3ms) SELECT COUNT(*) FROM "products" WHERE "products"."type" IN ('Product') 
    (0.1ms) begin transaction 
    (0.1ms) rollback transaction 
ActiveRecord::RecordInvalid: Validation failed: User can't be blank 
    from ~/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in `save!' 

私はNullUserサブクラスUserと用途を持つことである最も魅力的なそのkludgey回避策の束、について考えてきました製品を作ることですしかし、それはまだハックのように思えます。これでRails Wayとは何ですか?

ありがとうございました。


関連の移行:

class AddUseridToProducts < ActiveRecord::Migration 
    def change 
    add_column :products, :user_id, :integer 
    end 
end 

以降:

class Changeuseridtobeoptionalforproducts < ActiveRecord::Migration 
    def change 
    change_column :products, :user_id, :integer, null: true 
    end 
end 
+0

'Product'モデルにあるすべてのバリデーションを投稿してください。 –

答えて

4

ユーザーの存在を確認する検証がありますか?もしそうなら、それを取り除く。あなたは、このオプションを渡す必要がありますこのような動作する場合は

3

Railsは絶対に箱から出して、これをサポートし、あなたの移行を確認し、あなたはそのように:null => falseなどの制約が含まれていますuser_id行?もしそうなら、それを取り出してください!

編集:@Rodrigo Diasの状態で、:null => trueに戻します。

また、製品モデルのユーザーリレーションシップに関する検証がないことを確認してください。

+1

を入力するか、単にnullに変更してください: –

+0

私はOPにマイグレーションを追加しました(改行が終了したため、ここに貼り付けなかった)。 – tsm

+0

私は 'change_column:products、:user_id、:integer、null:true'でマイグレーションを行いましたが、何もしませんでした。 – tsm

108

レール5のためだけの更新は、:Railsの5では

belongs_to :user, optional: true 

を我々はbelongs_toの関連付けを定義したときに、あることが要求されますデフォルトで関連レコードが存在します。

+1

Ughhh ...すべてのリリースノートを読む必要があります。 ? –

+0

私はこれをレール5で試しましたが、オプションですが、外来キーフィールドに存在しない値を入力すると問題になります。この場合、プライマリ・テーブルでは使用できないエラーが発生します。だからこれを修正する方法は? –

+0

あなたは実際にどのような関係でこれを行うことができます、もしそれが数字でもなくてもいなければ、あなたが置いたものがto_iをしようとすると信じています。 belongs_toが提供するインスタンスメソッドを使用する必要があります。このメソッドを使用して関連付けを作成すると不正な値が防止され、Association.users.buildおよびUserを使用します。私の場合は、オプションのtrueを使用している特定のレコードに対して、既存のレコードが関連付けられていないことを避けるためにbuild_associationを使用します。このレコードはゲストユーザを許可しますので、Association.user = current_user current_userはゼロです。エラーは表示されません – Alexis

関連する問題