0

したがって、Ryan Bates Railsキャスト(http://railscasts.com/episodes/196-nested-model-form-revised)に基づいて、ネストされたフォームを作成しています。私が理想的に動作させようとしているrailsアプリケーションの部分は、次のことを行います。

  • 現在のユーザーに質問させます
  • その後、その質問に対する回答を提供します

すべてが入力された後にフォームを送信しようとすると、次のエラーが発生し続けることを除いて、すべてが機能するようになりました。

undefined method `meter_id' for nil:NilClass

app/models/answer.rb:13:in `associate_with_meter_id'
app/controllers/questions_controller.rb:13:in `create'

何が悪いのかはわかっていると思いますが、どうすれば修正できるのかわかりません。Meter_idは、正しい値が渡されていないため、未定義の値を返しています。(回答の)meter_idを(ユーザーの)meter_idに関連付けるメソッドは次のとおりです。

def associate_with_meter_id
    self.meter_id = user.meter_id
end

これが私のユーザーモデルの一部です

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me,
                  :home_size_sf, :meter_id, :avg_monthly_kwh, :discovery_score,
                  :questions_attributes, :answers_attributes


  has_many :data_records, :foreign_key => :meter_id, :primary_key => :meter_id, :class_name => "DataRecord"

  has_many :questions
  has_many :answers

  accepts_nested_attributes_for :questions, :answers

これが質問モデルです

class Question < ActiveRecord::Base
    attr_accessible :description, :taxonomy, :user_id, :answers_attributes
  belongs_to :user
  has_many :answers
  accepts_nested_attributes_for :answers
  validates :description, presence: { :on => :create }
  validates :taxonomy, presence: { :on => :create }
  def relevance_score
    rand
  end
end

これが質問コントローラーです

class QuestionsController < ApplicationController
  respond_to :html, :json

  def index
    @question = current_user.questions.new
    @questions = current_user.questions.all
  end

  def create
    @question = current_user.questions.new(params[:question])
    if !params[:update_button]
      if @question.valid?
        if params[:next_button] || !@question.save
          render 'index'
        elsif !params[:next_button] && params[:submit_button] && @question.save
          flash[:success] = "Your question and answer have been saved."
          respond_with @question, :location => questions_path
        end
      else
        render 'index'
      end
    else
      render 'index'
    end
  end

  def next
    @question = current_user.unanswered.first
    @answer = Answer.new(:question => @question, :user => current_user)
    respond_to do |format|
      format.js
    end
  end
end

回答モデル

class Answer < ActiveRecord::Base
  attr_accessible :value, :user_id, :meter_id, :question_id
  belongs_to :user
  belongs_to :question

  validates :value, presence: true, :numericality => true

  before_save :associate_with_meter_id



  def associate_with_meter_id
    self.meter_id = user.meter_id **(<-- line 13 from the error message)**
  end

end

コントローラーに答える

class AnswersController < ApplicationController
  respond_to :html, :json

  def index
    @answers = current_user.answers
  end

  def create
    @answer = current_user.answers.create(params[:answer])
    if @answer.save
      flash[:notice] = "Thanks for for answer. Please continue with your input...."
      respond_with @answer, :location => root_url
    end
  end

end

データベーススキーマ

ActiveRecord::Schema.define(:version => 20120210184340) do

  create_table "answers", :force => true do |t|
    t.integer  "meter_id"
    t.integer  "user_id"
    t.integer  "question_id"
    t.float    "value"
    t.float    "what_if_value"
    t.datetime "created_at",    :null => false
    t.datetime "updated_at",    :null => false
  end

  create_table "data_records", :force => true do |t|
    t.datetime "timestamp"
    t.float    "value"
    t.integer  "meter_id"
    t.string   "status_code"
  end

  create_table "questions", :force => true do |t|
    t.string   "description"
    t.string   "taxonomy"
    t.string   "coeff"
    t.float    "rsquare",     :default => 0.0
    t.string   "rank"
    t.string   "responses"
    t.string   "skips"
    t.string   "avganswer"
    t.float    "pval",        :default => 0.0
    t.float    "quality",     :default => 0.0
    t.integer  "user_id"
    t.datetime "created_at",                   :null => false
    t.datetime "updated_at",                   :null => false
  end

  create_table "setup_constants", :force => true do |t|
    t.float "exp_model",      :default => 0.0
    t.float "exp_pval_const", :default => 0.0
  end

  create_table "users", :force => true do |t|
    t.integer  "meter_id"
    t.float    "home_size_sf",           :default => 1000.0
    t.text     "notifications"
    t.float    "avg_monthly_kwh"
    t.float    "ee_score"
    t.string   "email",                  :default => "",     :null => false
    t.string   "encrypted_password",     :default => "",     :null => false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          :default => 0
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                                 :null => false
    t.datetime "updated_at",                                 :null => false
  end

  add_index "users", ["email"], :name => "index_users_on_email", :unique => true
  add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true

end

ノート:

回答モデル(上記)では、次の行があります。

self.meter_id = user.meter_id

回答モデルのmeter_idをユーザーモデルのmeter_idに関連付けます。これが問題だと思います。上記の行を次のように変更してみました。

self.meter_id = 2

そして、すべてが正常に機能したので、user.meter_idが未定義であることは明らかです。そのため、ネストされたフォームを介してその値を渡す方法がわかりません。隠しフィールドを使用してみましたが、うまくいきませんでした(以下は、form_for @questions内のネストされたfields_for:answersです):

<fieldset>
    <%= f.label "Yes" %>
  <%= f.radio_button :value, 1 %>
  <%= f.label "No" %>
  <%= f.radio_button :value, 0 %>
  <%= f.hidden_field :user_id %>
  <%= f.hidden_field :question_id %>
  <%= f.hidden_field :meter_id %>
</fieldset>
4

1 に答える 1

1

まず、セキュリティ上の理由から、現在のユーザーをビューに渡したくない場合があります。代わりに、コントローラーから実行します。

開始点(current_userがあると仮定):

@answer = current_user.answers.create(params[:answer].merge(:user => current_user))

そこから、ユーザーを回答モデルに渡す方法はあなた次第です。ただし、これを使用することはできます。

self.meter_id = question.user.meter_id

それが適切であると仮定します。

于 2012-06-08T14:50:55.610 に答える