Ruby on Rails自动变量名称(Plural vs Singular)

时间:2016-04-29 14:40:01

标签: ruby-on-rails ruby variables activerecord plural

我正在构建一个rails应用程序,它有几个具有完全相同结构的测验:

  • @quiz_bf@quiz_bs
  • 等名称 每个测验的
  • new.html.erbedit.html.erb次观看
  • 存储每个测验的实际测验问题的部分_quiz.html.erb
  • 每个单独测验的模型和控制器
  • 两个地方(主导航和用户个人资料页面)包含指向new视图的链接(或edit视图,如果有人已经参加了测验,则由erb决定if /每个测验的其他陈述

我成功地设置了第一个测验,但由于我是Ruby的新手,我犯了一个(可怕的)错误,设置了一个以-s(quiz_bs)结尾的变量名,用于单数版本测验。这对Ruby的单数与复数命名约定造成了严重破坏。

我目前已经设置了第二个测验(quiz_bf)的代码,但是我的控制器中新测验的定义中出现了undefined method 'quiz_bfs' for #<User:0x007fb9a3247f98>的无方法错误。

这是我的控制人员:

class QuizBfController < ApplicationController
before_action :require_sign_in

def show
  @quiz_bf = QuizBf.find(params[:id])
end

def new
  @quiz_bf = current_user.quiz_bfs || current_user.build_quiz_bfs
end

def create
  @quiz_bf = QuizBf.new

  @quiz_bf.bf01 = params[:quiz_bfs][:bf01]
  @quiz_bf.bf02 = params[:quiz_bfs][:bf02]
  @quiz_bf.bf03 = params[:quiz_bfs][:bf03]
  @quiz_bf.bf04 = params[:quiz_bfs][:bf04]
  @quiz_bf.bf05 = params[:quiz_bfs][:bf05]
  @quiz_bf.bf06 = params[:quiz_bfs][:bf06]
  @quiz_bf.bf07 = params[:quiz_bfs][:bf07]
  @quiz_bf.bf08 = params[:quiz_bfs][:bf08]
  @quiz_bf.bf09 = params[:quiz_bfs][:bf09]
  @quiz_bf.bf10 = params[:quiz_bfs][:bf10]

  @quiz_bf.user = current_user

  if @quiz_bf.save
    flash[:notice] = "Quiz results saved successfully."
    redirect_to user_path(current_user)
  else
    flash[:alert] = "Sorry, your quiz results failed to save."
    redirect_to welcome_index_path
  end
  end

  def edit
    @quiz_bf = QuizBf.find(params[:id])
  end

  def update
  @quiz_bf = QuizBf.find(params[:id])

  @quiz_bf.assign_attributes(quiz_bfs_params)

  if @quiz_bf.save
    flash[:notice] = "Post was updated successfully."
    redirect_to user_path(current_user)
    else
    flash.now[:alert] = "There was an error saving the post. Please try again."
    redirect_to welcome_index_path
    end
    end

    private
    def quiz_bfs_params
    params.require(:quiz_bfs).permit(:bf01, :bf02, :bf03, :bf04, :bf05, :bf06, :bf07, :bf08, :bf09, :bf10)
    end

    end

这是我的模特(用户has_one :quiz_bf):

class QuizBf < ActiveRecord::Base
before_save :set_bfcode

def set_bfcode
  self.bfcode = "#{self.bf01}#{self.bf02}#{self.bf03}-#{self.bf04}#{self.bf05}#{self.bf06}-#{self.bf07}#{self.bf08}#{self.bf09}#{self.bf10}"
end

belongs_to :user
validates :user, presence: true
end

这是我的用户模型:

class User < ActiveRecord::Base
before_save { self.email = email.downcase }

validates :name, length: { minimum: 1, maximum: 100 }, presence: true
validates :password, presence: true, length: { minimum: 6 }, unless: :password_digest
validates :password, length: { minimum: 6 }, allow_blank: true
validates :email,
        presence: true,
        uniqueness: { case_sensitive: false },
        length: { minimum: 3, maximum: 254 }

has_secure_password

has_one :quiz_bs
has_one :quiz_bf

以下是我的测验部分中的绅士位:

<%= form_for @quiz_bf do |f| %>

...

<%= f.submit "Submit Answers" %>

以下是我在new视图中的关联方式:

<%= render partial: "quiz", locals: { url: quiz_bfs_path, method: :post } %>

我的edit观点:

<%= render "quiz", url: quiz_bf_path(@quiz_bf), method: :put  %>

并且(最后)在这里我是如何从application视图链接到它的:

          <% if current_user.quiz_bfs == nil? %>
             <%= link_to "Body Flexibility Quiz", quiz_bf_path %>
          <% else %>
             <%= link_to "Body Flexibility Quiz ✓", edit_quiz_bf_path(current_user.quiz_bfs) %>
          <% end %>

我的用户show页面:

  <% if @user.quiz_bfs == nil %>
    <p><%= link_to "Test Your Body Flexibility", new_quiz_bf_path %></p>
  <% else %>
    <h3><%= @user.quiz_bfs.bfcode %></h3>
    <p><%= link_to "Retest Results", edit_quiz_bf_path(@user.quiz_bfs) %></p>
  <% end %>

我知道这段代码成功地用于quiz_bs,但正如你在我的rake路线中看到的那样(如下所示),我的愚蠢变量名称的复数/单数问题使我很难看到实际命名的内容什么。拥有比我更有经验的红宝石眼睛的人能告诉我我需要改变什么吗?

        quiz_bs GET    /quiz_bs(.:format)             quiz_bs#index
                POST   /quiz_bs(.:format)             quiz_bs#create
     new_quiz_b GET    /quiz_bs/new(.:format)         quiz_bs#new
    edit_quiz_b GET    /quiz_bs/:id/edit(.:format)    quiz_bs#edit
         quiz_b GET    /quiz_bs/:id(.:format)         quiz_bs#show
                PATCH  /quiz_bs/:id(.:format)         quiz_bs#update
                PUT    /quiz_bs/:id(.:format)         quiz_bs#update
                DELETE /quiz_bs/:id(.:format)         quiz_bs#destroy
  quiz_bf_index GET    /quiz_bf(.:format)             quiz_bf#index
                POST   /quiz_bf(.:format)             quiz_bf#create
    new_quiz_bf GET    /quiz_bf/new(.:format)         quiz_bf#new
   edit_quiz_bf GET    /quiz_bf/:id/edit(.:format)    quiz_bf#edit
        quiz_bf GET    /quiz_bf/:id(.:format)         quiz_bf#show
                PATCH  /quiz_bf/:id(.:format)         quiz_bf#update
                PUT    /quiz_bf/:id(.:format)         quiz_bf#update
                DELETE /quiz_bf/:id(.:format)         quiz_bf#destroy

1 个答案:

答案 0 :(得分:1)

未定义的方法错误

未定义方法的问题可能与调用是一个复数调用(has_one :quiz_bs has_one :quiz_bf )有关,它希望你有一个has_many关联,而你的模型只定义一个has_one关联:

quiz_bfs

使用quiz_bf是一个拼写错误,应该是current_user.quiz_bfs,b)has_one不正确,或者c)您不需要调用@quiz_bf all将值赋给current_user.quiz_bfs。在不知道更多细节的情况下很难分辨,但看起来你可以删除quiz_bs

路线上的奖金

虽然不是这个问题,但具体而言,你提到了以's'结尾的资源的痛苦被视为复数。如果您还没有看到它,可以适当地命名config/routes.rb条路线。为此,您可以在resources :quiz_bs, as: :quiz_bs 文件中使用此表单:

QuizBsController

应该为您提供您想要的路线助手名称。您可以在Overriding Named HelpersRails Routing from the Outside In部分详细了解相关内容。

您可能还想为控制器controller:命名,并且可以使用资源路由定义上的resources :quiz_bs, controller: 'quiz_bs' 覆盖来执行此操作。试试这个,看看它是否能为你提供合适的控制器:

resources :quiz_bs, controller: 'quiz_bs', as: :quiz_bs

您可以始终将两种路线方法结合使用,并使用以下内容:

{{1}}

查看Specifying a Controller to UseRails Routing from the Outside In部分,了解更多信息和使用详情。