Rails:如何访问我的@results对象的属性

时间:2014-12-11 13:30:41

标签: ruby-on-rails ruby activerecord controller

试图访问' answer1'我的@results对象的属性来自:

@results.answer1  

...我在线查看,并尝试了此处建议的解决方案...
get attribute of ActiveRecord object by string
..但我似乎无法访问我传递的ActiveRecord @results对象的属性。

最初用户被定向到/ quizzes / new视图,QuizzesController #new动作如下所示:

def new
        @user = current_user
        @quiz_answer = current_user.quiz_answers.build
    end

@quiz_answer因此可供视图访问并传递到form_for。 编辑:这是我的表单(部分呈现为quizzes / new.html.erb的一部分):

<%= form_for(@quiz_answer) do |f| %>
  <p>
    <%= f.check_box(:answer1) %>
    <%= f.check_box(:answer2) %>
    <%= f.check_box(:answer3) %>
    <%= f.check_box(:answer4) %>
    <%= f.check_box(:answer5) %>
    <%= f.check_box(:answer6) %>
    <%= f.check_box(:answer7) %>
    <%= f.check_box(:answer8) %>
  </p>
  <p>
    <%= f.submit("Get my results!") %>
  </p>
<% end %>

当用户单击表单上的提交时,将触发QuizAnswers #create操作,该操作将重定向到results_path(ResultsController中的索引操作)。

因此,由于ResultsController中的索引操作:

,因此视图可以访问@results
def index
    # in order to access all the results in our view...
    @results = current_user.quiz_answers
  end

在我的结果/索引视图中,这个

<p><%= @results %></p>

将以下内容输出到页面:

#<QuizAnswer::ActiveRecord_Associations_CollectionProxy:0x5191b30>

...所以对象不是零。

但是当我尝试访问&#39; answer1&#39; @results的属性,来自:

<p><%= @results[answer1] %></p>

<p><%= @results.read_attribute(answer1) %></p>

...我收到以下错误:

undefined local variable or method `answer1' for #<#<Class:0x72384d8>:0x71b6d10>

最后,在我的routes.rb中,我定义了以下资源:

resources :quizzes
  resources :results  
  resources :quiz_answers

  resources :users do
    resources :posts

  end

但是当我加入资源时:quiz_answers&#39;作为资源的一部分:用户&#39; (紧靠&#39;资源:帖子&#39;行)我收到以下错误:

undefined method `quiz_answers_path' for #<#<Class:0x5310618>:0x5411b80>

...当我去测验/新页面时。

所以我的问题是:如果quiz_answers需要是作为用户资源的一部分包含的资源,我如何将current_user.quiz_answers传递给form_for?如果它必须成为&#39;的一部分。用户资源,如何访问quiz_answers的属性?

再一次,如果我有任何假设或做错的事情,请随时解释一下&#39; Rails方式&#39;这样做。

修改

我想我已经被要求提供模型,控制器和迁移,所以在这里:

用户控制器:

class UsersController < ApplicationController
    def show
        @user = current_user
    end

    def edit
        @user = User.find(params[:id])
    end

    def update 
        @user = User.find(params[:id])
        @user.update_attributes(user_params)
        if @user.save
            redirect_to(@user)
        else
            render 'edit'
        end
    end

    private
    # Using a private method to encapsulate the permissible parameters is just a good pattern
    # since you'll be able to reuse the same permit list between create and update. Also, you
    # can specialize this method with per-user checking of permissible attributes.
    def user_params
      params.require(:user).permit(:name, :age, :email, :section)
    end
end

测验答案控制器:

class QuizAnswersController < ApplicationController
    def new
        @user = current_user
        @quiz_answer = current_user.quiz_answers.build
    end

    def create 
        redirect_to results_path
    end

    private 

    def post_params
        params.require(:quiz_answer).permit(:body, :user_id)
    end
end

结果控制器:

class ResultsController < ApplicationController
  def index
    # in order to access all the results in our view...
    @results = current_user.quiz_answers
  end
end

schema.rb(请告诉我这是否是您需要的,迁移方式):

ActiveRecord::Schema.define(version: 20141002130233) do

  create_table "posts", force: true do |t|
    t.text     "body"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
  end

  add_index "posts", ["user_id"], name: "index_posts_on_user_id"

  create_table "quiz_answers", force: true do |t|
    t.integer  "user_id"
    t.string   "answer1"
    t.string   "answer2"
    t.string   "answer3"
    t.string   "answer4"
    t.string   "answer5"
    t.string   "answer6"
    t.string   "answer7"
    t.string   "answer8"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "quiz_answers", ["user_id"], name: "index_quiz_answers_on_user_id"

# Could not dump table "users" because of following NoMethodError
#   undefined method `[]' for nil:NilClass

end

QuizAnswer模型:

class QuizAnswer < ActiveRecord::Base
    belongs_to :user

end

用户模型很长,但它包括:

has_many :posts
has_many :quiz_answers

我希望有所帮助!

2 个答案:

答案 0 :(得分:0)

所有评论都完全有效,即您将CollectionProxy设置为变量@results,但您的主要问题是QuizAnswersController中的create操作 nothing 除外重定向到results_path

虽然Rails会为您做很多工作,但您必须在create操作中处理表单提交的参数。

您的代码存在很多问题,因此我建议您阅读this part of the Rails Guide on Action Controller。您还需要调整QuizAnswersController中的post_params方法,因为您只允许bodyuser_id属性进行批量分配,这意味着您将无法执行任何操作answer1等属性,除非您手动分配它们。

话虽如此,他们在表格中做了什么?据我所知,他们只是设置真值或假值的复选框?

您的QuizAnswersController需要看起来像这样。

class QuizAnswersController < ApplicationController
  ...

  def create
    @quiz_answer = current_user.quiz_answers.new(post_params) #from private method
    if @quiz_answer.save
      redirect_to results_path
    else
      #error handle here
    end
  end

  private 

  def post_params
    params.require(:quiz_answer).permit(:answer1, :answer2) #add other attributes here
  end
end

编辑:您说您在QuizAnswer模型上允许body属性,但根据您的数据库架构,这不属于其属性之一,因此我更新了代码。

答案 1 :(得分:0)

由于@results是一个包含属于当前用户的所有quiz_answer的关系:

@results = current_user.quiz_answers

您的结果/ index.erb 视图将包含以下内容:

<%- @results.each do |quiz_answer| %>
   <%# ... some code shows answer data like %>
   <h4>Quiz Answer</h4>
   <p><%= quiz_answer.answer1 %></p>
   <p><%= quiz_answer.answer2 %></p>
   <p><%= quiz_answer.answer3 %></p>
   <p><%= quiz_answer.answer4 %></p>
   <p><%= quiz_answer.answer5 %></p>
   <p><%= quiz_answer.answer6 %></p>
   <p><%= quiz_answer.answer7 %></p>
   <p><%= quiz_answer.answer8 %></p>
<%- end %>

如果没有为当前用户分配quiz_answer,则将在输出中跳过该表单。可能您应该将name字段添加到quiz_answer表格,然后您可以将其添加到上面的表格中:

   <p>Name: <%= quiz_answer.name %></p>

要将quiz_answer分配中新创建的create添加到QuizAnswersController分配给当前用户,如下所示:

class QuizAnswersController < ApplicationController
   def create 
      quiz_answer = QuizAnswer.create(params.require(:quiz_answer).permit(:answer1)
      current_user.quiz_answers << quiz_answer
      redirect_to results_path
      # require 'pry'
      # binding.pry
   end
end

quiz_answer.save!之后,请检查current_user.quiz_answers,确保#size不为空。您可以使用pry gem来调试它。只需将其添加到 Gemfile ,然后作为断点插入到所需位置,并使用requirebinding取消注释这两行。