22

多くのタスクを持つプロジェクト リソースがあります。タスク モデルにproject_id追加することで、すべてのタスクに があることを確認したいと思います。validates_presence_of :project_id

ただし、タスクを含む新しいプロジェクトを作成する場合、レコードが保存されるまで project_id は使用できないため、使用できませんvalidates_presence_of :project_id

私の質問は、タスク モデルで project_id の存在を検証するにはどうすればよいですか? すべてのタスクに親があることを確認したい。

...

class Project < ActiveRecord::Base

  has_many :tasks, :dependent => :destroy
  accepts_nested_attributes_for :tasks, :allow_destroy => true

...

class Task < ActiveRecord::Base

 belongs_to :project
 validates_presence_of :project_id
4

7 に答える 7

18

あなたのコードは動作します:

  • validates_presence_of :project を実行すると、プロジェクトがそこにある限り検証されます。ただし、プロジェクトが保存されていない場合でも、タスクを保存できます。
  • validates_presence_of :project_id の場合、保存された値を示す整数がそこにある必要があります。

ポイントを証明する rSpec を次に示します。:project_id を検証すると、プロジェクトを保存せずにタスクを保存することはできません。

class Task < ActiveRecord::Base
  belongs_to :project
end

/specs/model_specs/task_spec.rb

require File.dirname(__FILE__) + '/../spec_helper'

describe Task do

  before(:each) do 
    @project = Project.new
  end

  it "should require a project_id, not just a project object" do
    task = Task.new
    task.project = @project
    Task.instance_eval("validates_presence_of :project_id")
    task.valid?.should == false
  end

  it "should not be valid without a project" do
    task = Task.new
    task.project = @project
    Task.instance_eval("validates_presence_of :project")
    task.valid?.should == false
    task.save.should == false
  end

end
于 2010-06-10T19:57:20.540 に答える
15

決定的な答えについては、こちらをご覧ください。

class Project < ActiveRecord::Base

  has_many :tasks, :dependent => :destroy, :inverse_of => :project
  accepts_nested_attributes_for :tasks, :allow_destroy => true

class Task < ActiveRecord::Base

 belongs_to :project
 validates_presence_of :project

あなたが私に尋ねるならそれほどエレガントではありません...それは透過的に検証する必要があります。

于 2010-08-19T11:40:15.410 に答える
3

何かわからないかもしれませんが、レールをだまそうとしているようです。どうしてこんな風にしないの?

class Task < ActiveRecord::Base
  belongs_to :project
  validate_presence_of :project
end
于 2010-06-09T22:20:25.210 に答える
2

これを見てください:

https://rails.lighthouseapp.com/projects/8994/tickets/2815-nested-models-build-should-directly-assign-the-parent

私が過去に行ったことの 1 つは add:validates_presence_of :parent_id, :on => :updateです。良くはありませんが、ネットを少し締めるのに役立ちます.

于 2010-06-10T08:24:18.680 に答える
2

私が対処したのと同じ問題を抱えていると思います。アカウントとユーザーの 2 つのモデルがあり、アカウントが作成されると、最初のユーザーが@account.users.build. User モデルにはvalidates_presence_of :account検証があります。

最初のユーザーが検証に合格するようにするために、次のコードを Account モデルに追加しました。

  before_validation_on_create :initialize_users

  def initialize_users
    users.each { |u| u.account = self }
  end
于 2010-12-06T22:30:27.113 に答える
0

あなたのProjectクラスは定義しなければなりません

accepts_nested_attributes_for :tasks

フォームの作成方法の詳細については、Railscastsのネストされたモデル フォームを参照してください。


編集:

フォームには、次のようなものが必要です。

_form.html.erb

<% form_for @project do |f| %> 
    # project fields...
    <% f.fields_for :tasks do |builder| %>
        <%= render 'task_fields', :f => builder %>
    <% end %>
    <p><%= link_to_add_fields "Add task", f, :tasks %></p>
    <%= f.submit %>
<% end %>

_task_fields.html.erb

<%= f.label :name, "Task name:" %>
<%= f.text_field :name %>
# task fields...
<%= link_to_remove_fields "Delete task", f, :tasks %>

link_to_add_fieldslink_to_remove_fieldsフィールドを動的に追加/削除するために application_helper で定義されているメソッドです。

于 2010-05-18T19:12:16.173 に答える