Rails 3.2 的隐藏属性未填充表单中的字段
Hidden attribute not populating field in form for Rails 3.2
我正在实施一个邀请系统,我希望 new user form
在表单的电子邮件地址字段中预填充用户的电子邮件地址(最终,我会重构它,所以它不是 form_field),这样用户就不必输入所有信息,只需输入密码即可。
我在 users.rb
模型中创建了 getter/setter 方法,如下所示:
def invitation_token
invitation.invitation_token if invitation
end
def invitation_token=(invitation_token)
self.invitation = Invitation.find_by_invitation_token(invitation_token)
end
邀请模型
class Invitation < ActiveRecord::Base
#--== ASSOCIATIONS
belongs_to :sender, :class_name => 'User'
has_one :recipient, :class_name => 'User'
#--== CALLBACKS
before_create :generate_token
before_create :recipient_is_not_registered
before_create :decrement_sender_count, :if => :sender
#--== VALIDATIONS
validates_presence_of :recipient_email
#validate :recipient_is_not_registered
validate :sender_has_invitations, :if => :sender
#--== METHODS
private
def recipient_is_not_registered
if User.find_by_email(recipient_email)
false
else
true
end
end
def sender_has_invitations
unless sender.invitation_limit > 0
redirect_to root_url
end
end
def generate_token #TODO: MOVE to lib/generate_token.rb
self.invitation_token = Digest::SHA1.hexdigest([Time.now, rand].join)
end
def decrement_sender_count
sender.decrement! :invitation_limit
end
end
用户控制器
class UsersController < ApplicationController
def new
@user = User.new(:invitation_token => params[:invitation_token])
@user.email = @user.invitation.recipient_email if @user.invitation
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id] = @user.id
redirect_to root_url, notice: "Thank you for signing up!"
else
render "new"
end
end
...
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :admin)
end
end
views/users/_form.html.erb
<%= form_for @user do |f| %>
<%= f.hidden_field :invitation_token %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.check_box :admin %>
<%= f.label :admin %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
我正在关注 Ryan Bates 的 RC#124 - Beta 邀请,但被困在这里。他的代码没有产生错误,所以我应该提到这是一个 Rails 3.2.18 应用程序。
当我重新加载表单时,用户的电子邮件未填充到表单中。相关日志显示:
Started GET "/signup.914823d28d07b747213ec3de47f89ad537169e34" for 127.0.0.1
at 2016-04-30 20:24:47 -0600
Processing by UsersController#new as
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."auth_token" = 'rOHiKmDcceytxi_t151YIQ' LIMIT 1
Invitation Load (0.0ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."invitation_token" IS NULL LIMIT 1
Rendered users/_form.html.erb (5.0ms)
Rendered users/new.html.erb within layouts/application (6.0ms)
Completed 200 OK in 102.0ms (Views: 25.0ms | ActiveRecord: 3.0ms)
看来 invitation_token 没有传入,因为日志显示它是 NULL。
我把RC代码从上到下看了一遍,没找到为什么没通过。
如有任何帮助,我们将不胜感激。谢谢。
更新:视图源的输出是:
<input id="user_invitation_token" name="user[invitation_token]" type="hidden" />
,所以没有传下去。
通过传递 value:
键在隐藏字段上设置值:
<%= f.hidden_field :invitation_token, value: some_value %>
我正在实施一个邀请系统,我希望 new user form
在表单的电子邮件地址字段中预填充用户的电子邮件地址(最终,我会重构它,所以它不是 form_field),这样用户就不必输入所有信息,只需输入密码即可。
我在 users.rb
模型中创建了 getter/setter 方法,如下所示:
def invitation_token
invitation.invitation_token if invitation
end
def invitation_token=(invitation_token)
self.invitation = Invitation.find_by_invitation_token(invitation_token)
end
邀请模型
class Invitation < ActiveRecord::Base
#--== ASSOCIATIONS
belongs_to :sender, :class_name => 'User'
has_one :recipient, :class_name => 'User'
#--== CALLBACKS
before_create :generate_token
before_create :recipient_is_not_registered
before_create :decrement_sender_count, :if => :sender
#--== VALIDATIONS
validates_presence_of :recipient_email
#validate :recipient_is_not_registered
validate :sender_has_invitations, :if => :sender
#--== METHODS
private
def recipient_is_not_registered
if User.find_by_email(recipient_email)
false
else
true
end
end
def sender_has_invitations
unless sender.invitation_limit > 0
redirect_to root_url
end
end
def generate_token #TODO: MOVE to lib/generate_token.rb
self.invitation_token = Digest::SHA1.hexdigest([Time.now, rand].join)
end
def decrement_sender_count
sender.decrement! :invitation_limit
end
end
用户控制器
class UsersController < ApplicationController
def new
@user = User.new(:invitation_token => params[:invitation_token])
@user.email = @user.invitation.recipient_email if @user.invitation
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id] = @user.id
redirect_to root_url, notice: "Thank you for signing up!"
else
render "new"
end
end
...
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :admin)
end
end
views/users/_form.html.erb
<%= form_for @user do |f| %>
<%= f.hidden_field :invitation_token %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.check_box :admin %>
<%= f.label :admin %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
我正在关注 Ryan Bates 的 RC#124 - Beta 邀请,但被困在这里。他的代码没有产生错误,所以我应该提到这是一个 Rails 3.2.18 应用程序。
当我重新加载表单时,用户的电子邮件未填充到表单中。相关日志显示:
Started GET "/signup.914823d28d07b747213ec3de47f89ad537169e34" for 127.0.0.1
at 2016-04-30 20:24:47 -0600
Processing by UsersController#new as
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."auth_token" = 'rOHiKmDcceytxi_t151YIQ' LIMIT 1
Invitation Load (0.0ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."invitation_token" IS NULL LIMIT 1
Rendered users/_form.html.erb (5.0ms)
Rendered users/new.html.erb within layouts/application (6.0ms)
Completed 200 OK in 102.0ms (Views: 25.0ms | ActiveRecord: 3.0ms)
看来 invitation_token 没有传入,因为日志显示它是 NULL。
我把RC代码从上到下看了一遍,没找到为什么没通过。
如有任何帮助,我们将不胜感激。谢谢。
更新:视图源的输出是:
<input id="user_invitation_token" name="user[invitation_token]" type="hidden" />
,所以没有传下去。
通过传递 value:
键在隐藏字段上设置值:
<%= f.hidden_field :invitation_token, value: some_value %>