Ruby on Rails 自动变量名称(复数或单数)
Ruby on Rails Automatic Variable Name (Plural vs Singular)
我正在构建一个 rails 应用程序,其中有几个结构完全相同的测验:
- 名称,例如
@quiz_bf
或 @quiz_bs
每个测验的 new.html.erb
和 edit.html.erb
观看次数
- 存储每个测验的实际测验问题的部分
_quiz.html.erb
- 每个单独测验的模型和控制器
- 两个地方(主导航和用户个人资料页面)为
new
视图(如果人们已经参加了测验,则为 edit
视图,link,由每个测验的 erb if/else 语句决定)
我成功地设置了第一个测验,但由于我是 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" %>
以下是我 link 从我的 new
观点看:
<%= render partial: "quiz", locals: { url: quiz_bfs_path, method: :post } %>
我的 edit
观点:
<%= render "quiz", url: quiz_bf_path(@quiz_bf), method: :put %>
(最后)这就是我 link 从我的 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 路由中看到的(如下所示),plural/singular 问题使我的白痴变量名变得很难看清什么实际上被命名为什么。 ruby 眼睛比我更有经验的人能告诉我我需要改变什么吗?
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
未定义的方法错误
未定义方法的问题可能与调用是复数调用 (quiz_bfs
) 有关,它期望您有一个 has_many 关联,而您的模型只定义了一个 has_one协会:
has_one :quiz_bs
has_one :quiz_bf
要么 a) quiz_bfs
的使用是一个拼写错误,应该是 quiz_bf
,b) has_one 不正确,或者 c) 您不需要调用current_user.quiz_bfs
根本没有给 @quiz_bf
赋值。在不知道更多细节的情况下很难说,但看起来你可以删除 current_user.quiz_bfs
.
路线奖励
虽然不是这个问题,但具体来说,您提到了以 's' 结尾的资源被视为复数的痛苦。如果您还没有看到它,您可以适当地命名您的 quiz_bs
路线。为此,您可以在 config/routes.rb
文件中使用此表格:
resources :quiz_bs, as: :quiz_bs
这应该 为您提供您想要的路由助手名称。您可以在 Overriding Named Helpers section of Rails Routing from the Outside In.
中阅读更多相关信息
您可能还想将您的控制器命名为 QuizBsController
,并且您可以在资源路由定义上使用 controller:
覆盖来做到这一点。试试这个,看看它是否为您提供了正确的控制器:
resources :quiz_bs, controller: 'quiz_bs'
您始终可以结合使用这两种路由方法并使用类似这样的方法:
resources :quiz_bs, controller: 'quiz_bs', as: :quiz_bs
查看 Specifying a Controller to Use section of Rails Routing from the Outside In 了解更多信息和使用详情。
我正在构建一个 rails 应用程序,其中有几个结构完全相同的测验:
- 名称,例如
@quiz_bf
或@quiz_bs
每个测验的 new.html.erb
和edit.html.erb
观看次数- 存储每个测验的实际测验问题的部分
_quiz.html.erb
- 每个单独测验的模型和控制器
- 两个地方(主导航和用户个人资料页面)为
new
视图(如果人们已经参加了测验,则为edit
视图,link,由每个测验的 erb if/else 语句决定)
我成功地设置了第一个测验,但由于我是 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" %>
以下是我 link 从我的 new
观点看:
<%= render partial: "quiz", locals: { url: quiz_bfs_path, method: :post } %>
我的 edit
观点:
<%= render "quiz", url: quiz_bf_path(@quiz_bf), method: :put %>
(最后)这就是我 link 从我的 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 路由中看到的(如下所示),plural/singular 问题使我的白痴变量名变得很难看清什么实际上被命名为什么。 ruby 眼睛比我更有经验的人能告诉我我需要改变什么吗?
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
未定义的方法错误
未定义方法的问题可能与调用是复数调用 (quiz_bfs
) 有关,它期望您有一个 has_many 关联,而您的模型只定义了一个 has_one协会:
has_one :quiz_bs
has_one :quiz_bf
要么 a) quiz_bfs
的使用是一个拼写错误,应该是 quiz_bf
,b) has_one 不正确,或者 c) 您不需要调用current_user.quiz_bfs
根本没有给 @quiz_bf
赋值。在不知道更多细节的情况下很难说,但看起来你可以删除 current_user.quiz_bfs
.
路线奖励
虽然不是这个问题,但具体来说,您提到了以 's' 结尾的资源被视为复数的痛苦。如果您还没有看到它,您可以适当地命名您的 quiz_bs
路线。为此,您可以在 config/routes.rb
文件中使用此表格:
resources :quiz_bs, as: :quiz_bs
这应该 为您提供您想要的路由助手名称。您可以在 Overriding Named Helpers section of Rails Routing from the Outside In.
中阅读更多相关信息您可能还想将您的控制器命名为 QuizBsController
,并且您可以在资源路由定义上使用 controller:
覆盖来做到这一点。试试这个,看看它是否为您提供了正确的控制器:
resources :quiz_bs, controller: 'quiz_bs'
您始终可以结合使用这两种路由方法并使用类似这样的方法:
resources :quiz_bs, controller: 'quiz_bs', as: :quiz_bs
查看 Specifying a Controller to Use section of Rails Routing from the Outside In 了解更多信息和使用详情。