在我的项目中,我使用了来自 Ryan Bigg的“多租户与Rails”的想法。每个帐户都有很多用户,帐户所有者可以邀请可以在发送给他们的电子邮件中点击"Accept invitation"
的用户。如果用户尚未在站点上登录/注册,则将呈现以下表单partial:
_anonymous_accept.html.erb :
<%= form_for(@invitation, url: accepted_invitation_path(params[:slug], @invitation), as: :user) do |f| %>
<%= f.label :email %>
<%= f.email_field :email, value: @invitation.email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Accept invitation", class: "button" %>
<% end %>
在提交时,这由邀请控制器中的已接受操作处理:
invitations_controller.rb :
def accept
store_location_for(:user, request.fullpath)
@invitation = Invitation.find_by!(token: params[:id])
end
def accepted
@invitation = Invitation.find_by!(token: params[:id])
if user_signed_in?
user = current_user
else
user_params = params[:user].permit(
:email,
:password,
:password_confirmation
)
user = User.create!(user_params)
sign_in(user)
end
current_account.users << user
flash[:success] = "Welcome! You have joined the #{current_account.name} account!"
redirect_to dashboard_path(params[:slug])
end
现在,这完全有效,直到我向表单添加更多字段。我不希望用户能够在不输入全名的情况下进行注册,因此我尝试将以下行添加到上面的代码示例中:
# added to the above sample from _anonymous_accept.html.erb
<%= f.label :firstname %>
<%= f.text_field :firstname, class: 'form-control' %>
<%= f.label :lastname %>
<%= f.text_field :lastname, class: 'form-control' %>
和此:
# added to the permitted user params in the accepted action in invitations_controller.rb
:firstname,
:lastname,
这些更改会破坏代码并向我提供此错误:
NoMethodError in Accounts::InvitationsController#accept
undefined method `firstname' for #<Invitation:0x0000000478cb58>
我无法看到此错误背后的逻辑,因为电子邮件和密码参数被接受,而不是名字和姓氏,当它们都来自同一个用户模型时。
有人有任何建议吗?
编辑:
从服务器日志中,按要求:
NoMethodError (undefined method `firstname' for #<Invitation:0x00000005a32208>):
app/views/accounts/invitations/_anonymous_accept.html.erb:12:in `block in _app_views_accounts_invitations__anonymous_accept_html_erb___2610584697742424634_41597720'
app/views/accounts/invitations/_anonymous_accept.html.erb:9:in `_app_views_accounts_invitations__anonymous_accept_html_erb___2610584697742424634_41597720'
app/views/accounts/invitations/accept.html.erb:9:in `_app_views_accounts_invitations_accept_html_erb__4463442190025129055_39118520'
编辑2:
# from db/schema.rb
create_table "invitations", force: :cascade do |t|
t.string "email"
t.integer "account_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "token"
end
# from models/invitation.rb
class Invitation < ActiveRecord::Base
belongs_to :account
before_create :generate_token
validates :email, presence: true
def to_param
token
end
private
def generate_token
self.token = SecureRandom.hex(16)
end
end
答案 0 :(得分:0)
您的表单适用于@invitation
实例对象,该对象没有任何firstname
或lastname
属性。
如果邀请与用户模型有关系,请在邀请时使用fields_for
或添加firstname
&amp; lastname
字段到您的邀请模式。
答案 1 :(得分:0)
可能问题来自于设计。试试这种方式,让我知道......
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << [:firstname, :lastname]
end
end
将此项添加到invitation.rb
文件中。
<强>更新强>
attr_accessor :firstname, :lastname
答案 2 :(得分:0)
好吧,我让它成功了。不过,这可能是一种廉价的解决方法。
我替换了这些行:
# from _anonymous_accept.html.erb
<%= f.label :firstname %>
<%= f.text_field :firstname, class: 'form-control' %>
<%= f.label :lastname %>
<%= f.text_field :lastname, class: 'form-control' %>
......用以下几行:
<%= label_tag("user[firstname]", "Your first name:") %>
<%= text_field_tag("user[firstname]") %>
<%= label_tag("user[lastname]", "Your last name:") %>
<%= text_field_tag("user[lastname]") %>
所以我想我只是绕过对未定义方法的调用:firstname和:lastname,形式为helper。
如果这真的很糟糕,请告诉我: - )