我有一个Rails应用程序,可在第一个用户注册时构建用户和组织(用户所属组织)。这工作正常,如果你没有插入,例如电子邮件地址(或使用不正确的地址)然后表单呈现相关的铁路错误消息就好了。我有额外的逻辑,确保第一个用户注册组织成为该组织的管理员用户,并允许他们将其他用户添加到该站点。如果您尝试使用现有的组织名称注册,则不允许这样做。
我的测试都很好,我正在使用骨架逻辑进行Hartl教程(而不是新的草案)提供的身份验证和授权。我最近注意到的是,当管理员用户为新用户输入空白表单时,应用程序将返回“组织”页面并显示成功消息。没有构建User对象(因此应用程序的某些部分仍在工作) - 我只是不希望发生这种情况(我希望显示错误消息)。我无法弄清楚这里发生了什么 - 为什么“validates”语句在这种情况下不会返回错误?无论如何 - 这是我的代码:
User.rb:
class User < ActiveRecord::Base
belongs_to :organization
has_many :sales_opportunities
before_save { self.email = email.downcase }
before_destroy :allocate_sales_opportunities_to_admin
before_create :create_remember_token
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
validates :organization, presence: true
Organization.rb:
class Organization < ActiveRecord::Base
validates :organization_name, presence: true, length: { maximum: 50 }, uniqueness: true
has_many :users, :inverse_of => :organization, dependent: :destroy
has_many :companies, :inverse_of => :organization, dependent: :destroy
has_many :products, :inverse_of => :organization, dependent: :destroy
has_many :competitors, :inverse_of => :organization, dependent: :destroy
accepts_nested_attributes_for :users
after_create :set_admin
def users_for_form
collection = users.where(organization_id: id)
collection.any? ? collection : users.build
end
private
def set_admin
if self.users.count == 1
self.users.first.update_attribute(:admin, true)
else
return true
end
end
end
用户控制器:
class UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update]
before_action :correct_user, only: [:edit, :update, :show]
before_action :admin_user, only: :destroy
def update
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
def create
if signed_in?
@organization = Organization.find(params[:organization_id])
@organization.users.create(user_params)
flash[:success] = "You added a new user to your organization. Send them their login details today!"
redirect_to @organization
else
@user = User.new(user_params)
if @user.save
sign_in @user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to @user
else
render 'new'
end
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, organization_attributes: [:organization_name, :organization_id])
end
#before filters
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
def correct_user
@user = User.find(params[:id])
@organization = @user.organization
redirect_to root_url, notice: "You are not permitted to visit that page. Please create an account or sign in" unless current_user?(@user) || @user.organization == current_user.organization
end
end
组织的控制者:
class OrganizationsController < ApplicationController
before_action :signed_in_user, only: [:edit, :update, :show]
before_action :correct_org, only: [:edit, :update, :show]
def new
@organization = Organization.new
@organization.users.build
end
def create
@organization = Organization.new(organization_params)
if @organization.save
@user = @organization.users.first
sign_in @user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to @user
else
render 'new'
end
end
我确信我在这里有一些丑陋的代码(组织和用户功能是我在学习RoR和偏离Hartl课程时创建的第一个新功能),我无法理解为什么当错误消息处理不是时,验证正在工作(没有创建用户对象)。为了完整性,这里是添加用户表单:
<% provide(:title, 'Add more users to your organization') %>
<div class-"container-fluid">
<h1>Sign up colleagues using the form below:</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="well">
<%= form_for([:organization, @user], :html => {:class => "form-horizontal"}) do |f| %>
<%= render 'shared/error_messages' %>
<div class="form-group">
<%= f.label :name, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :name, :placeholder => "What's their name?" %>
</div>
</div>
<div class="form-group">
<%= f.label :email, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :email, :placeholder => "Enter their email address" %>
</div>
</div>
<div class="form-group">
<%= f.label :password, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.password_field :password, :placeholder => "Provide a password" %>
</div>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Repeat Password", :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.password_field :password_confirmation, :placeholder => "Repeat password" %>
</div>
</div>
<%= f.submit "Add new user account", class: "btn btn-large btn-success" %>
<% end %>
</div>
</div>
</div>
</div>
以下是新组织/用户组合的工作表单:
<% provide(:title, 'Sign up') %>
<div class="container-fluid">
<h1>Sign up!</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="well">
<%= form_for(@organization, :html => {:class => "form-horizontal"}) do |f| %>
<%= render 'shared/org_error_messages' %>
<div class="form-group">
<%= f.label :organization_name, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :organization_name, :placeholder => "Who do you work for?" %>
</div>
</div>
<%= f.fields_for :users, @organization.users_for_form do |user| %>
<div class="form-group">
<%= user.label :name, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.text_field :name, :placeholder => "What's your name?" %>
</div>
</div>
<div class="form-group">
<%= user.label :email, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.text_field :email, :placeholder => "Email" %>
</div>
</div>
<div class="form-group">
<%= user.label :password, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.password_field :password, :placeholder => "Enter password - minimum 6 characters" %>
</div>
</div>
<div class="form-group">
<%= user.label :password_confirmation, "Repeat Password", :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= user.password_field :password_confirmation, :placeholder => "Repeat password" %>
</div>
</div>
<%= user.hidden_field :organization_id, input_html: {value: @organization.id} %>
<% end %>
<%= f.submit "Create my account", class: "btn btn-large btn-success" %>
<% end %>
</div>
</div>
</div>
<div>
我哪里错了?
编辑 - 这是上述情况发生时来自我的控制台的日志:
Processing by UsersController#new as HTML
Parameters: {"organization_id"=>"1"}
Rendered shared/_error_messages.html.erb (0.1ms)
Rendered users/new.html.erb within layouts/application (3.4ms)
Rendered layouts/_shim.html.erb (0.0ms)
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'b8cabbe1e1514f14be24f95d48248ad716e11342' LIMIT 1
Organization Load (0.3ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
Rendered layouts/_header.html.erb (3.9ms)
Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 28ms (Views: 26.0ms | ActiveRecord: 0.9ms)
Started POST "/organizations/1/users" for 127.0.0.1 at 2014-10-05 22:22:15 +0630
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fKx7bdWtC7bmBKMRF3ivwBlmJXzrcWJ16dYYOfNLBC0=", "user"=>{"name"=>"", "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Add new user account", "organization_id"=>"1"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'b8cabbe1e1514f14be24f95d48248ad716e11342' LIMIT 1
Organization Load (0.4ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
(0.3ms) BEGIN
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('') LIMIT 1
(0.8ms) COMMIT
Redirected to http://0.0.0.0:3000/organizations/1
Completed 302 Found in 14ms (ActiveRecord: 2.7ms)
Started GET "/organizations/1" for 127.0.0.1 at 2014-10-05 22:22:15 +0630
Processing by OrganizationsController#show as HTML
Parameters: {"id"=>"1"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'b8cabbe1e1514f14be24f95d48248ad716e11342' LIMIT 1
Organization Load (0.4ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", "1"]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."organization_id" = $1 [["organization_id", 1]]
Rendered organizations/_users_index.html.erb (1.0ms)
Organization Load (0.4ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" = $1 LIMIT 1 [["id", 1]]
Company Load (0.6ms) SELECT "companies".* FROM "companies" WHERE "companies"."organization_id" = $1 [["organization_id", 1]]
Competitor Load (0.4ms) SELECT "competitors".* FROM "competitors" WHERE "competitors"."organization_id" = $1 [["organization_id", 1]]
Product Load (0.4ms) SELECT "products".* FROM "products" WHERE "products"."organization_id" = $1 [["organization_id", 1]]
Rendered organizations/show.html.erb within layouts/application (13.3ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (0.6ms)
Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 37ms (Views: 30.6ms | ActiveRecord: 3.1ms)
答案 0 :(得分:0)
我认为这与我在进一步测试后处理创建新用户的方式有关。以下代码几乎肯定是错误所在:
def create
if signed_in?
@organization = Organization.find(params[:organization_id])
@organization.users.create(user_params)
flash[:success] = "You added a new user to your organization. Send them their login details today!"
redirect_to @organization
else
@user = User.new(user_params)
if @user.save
sign_in @user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to @user
else
render 'new'
end
end
end
如果我正在测试用户是否已登录,则选择会导致向当前组织添加新用户或从头开始创建。我需要的是一种测试@ organization.users.create是否成功的方法(或者我可能需要@ organization.users.new),如果它验证失败,那么我需要渲染“users / new”而不是返回到@organization路径并显示已创建新用户的(明显不正确的)闪存。
任何人都有任何想法我如何测试这个?我尝试了一个快速的if / else测试(按照“if @ organization.users.create ...... else:渲染用户/新页面”这一行),但后来我收到了一堆表单错误,因为我没有定义页面正在创建的对象。
答案 1 :(得分:0)
我通过更改用户控制器中的create函数解决了这个问题 - 无论表单中的错误消息如何,我都在创建一个新的@ organization.user。相反,我需要使用@user = @ organization.users.new,然后使用相同的if @ user.save ...测试适用于新用户。请参阅以下代码了解其修复方法:
def create
if signed_in?
@organization = Organization.find(params[:organization_id])
@user = @organization.users.new(user_params)
if @user.save
flash[:success] = "You added a new user to your organization. Send them their login details today!"
redirect_to @organization
else
render 'new'
end
else
@user = User.new(user_params)
if @user.save
sign_in @user
flash[:success] = "Thanks for signing up with My App! This is your profile page, be sure to take a look at the support link in the footer"
redirect_to @user
else
render 'new'
end
end
end