我正在使用Devise在我的应用程序中构建注册/身份验证系统。
查看了很多用于向设计模型添加信息的资源(例如用户名,传记,头像URL等等)[资源包括Jaco Pretorius' website,this (badly formed) SO question,{{3} }。
这一切都很好,很好 - 它有效。但我的问题是它保存到用户模型,根据and this SO question(database normalizations),它实际上应该保存到通过连接的用户的子模型expect(sportsOutputElement.props.children).to.eql([ {id: 100, text: 'car racing'}, {id: 10, text: 'hello vworld'}, {id: 100, text: 'car racing'} ]);
和has_one
。
到目前为止,我已经通过Devise创建了一个belongs_to
模型。我还通过User
脚本创建了UserProfile
模型。
user.rb (供参考)
rails generate
user_profile.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
has_one :user_profile, dependent: :destroy
end
timestamp_create_user_profiles.rb
class UserProfile < ActiveRecord::Base
belongs_to :user
end
我现在的问题是,如何收集这两种模型的信息,并通过设计登记表确保所有信息都在正确的位置?
我已经看到有关创建状态机的资源(also referencing this SO question和AASM。我还看到了有关创建the answer to this SO question和a wizard with WICKED的信息关于同一主题。
对于我的用例,这些似乎都是太复杂。有没有办法简单地将输入与设计分开,并确保最终在正确的位置?
答案 0 :(得分:3)
我认为,不是简单地评论引导我做出最终答案的答案,我会将答案存档在这里以防将来有人试图找到这个答案:< / p>
我将假设你有一些像我上面那样的设置。
第一步是您需要将用户控制器修改为accept_nested_attributes_for
配置文件引用,并向模型添加实用程序方法,以便在代码中请求时,应用程序可以检索构建的配置文件模型或构建一个
用户模型最终看起来像这样:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
has_one :user_profile, dependent: :destroy
accepts_nested_attributes_for :user_profile
def user_profile
super || build_user_profile
end
end
其次,您需要修改您的注册/ account_update表单,以便能够将此辅助模型的属性传递到控制器中,并最终能够为父模型构建配置文件。
您可以使用f.fields_for
。
在表单中添加以下内容:
<%= f.fields_for :user_profile do |user_profile_form| %>
<%= user_profile_form.text_field :attribute %>
<% end %>
在我的具体案例中的一个例子是:
<%= f.fields_for :user_profile do |user_profile_form| %>
<div class="form-group">
<%= user_profile_form.text_field :username, class: "form-control", placeholder: "Username" %>
</div>
<% end %>
最后,您需要告诉Devise它应该接受这个新的参数哈希并将其传递给模型。
如果你已经创建了自己的RegistrationsController和扩展的Devise,它应该类似于:
class RegistrationsController < Devise::RegistrationsController
private
def sign_up_params
params.require(:user).permit(:email, :password, user_profile_attributes: :username)
end
end
(当然,针对您的具体用例进行适当的更改。)
如果您只是将Devise清理方法添加到应用程序控制器中,它应该类似于:
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) {|u|
u.permit(:email, :password, user_profile_attributes: :username)}
end
end
(同样,针对您的具体用例进行适当的更改。)
关于user_profile_attributes: :username
的小记:
请注意,这是一个哈希。如果您传递了多个属性,例如account_update
(提示提示),则需要像user_profile_attributes: [:attribute_1, :attribute_2, :attribute_3]
那样传递它们。
答案 1 :(得分:1)
请查看RailsCasts.com网站。
有几个关于嵌套模型表单的有趣的railscast:
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
http://railscasts.com/episodes/196-nested-model-form-revised
另请查看accepts_nested_attributes_for
或查看此问题: Profile model for Devise users?
答案 2 :(得分:1)
另请注意,对于Devise 4.2,&#39; .for&#39;不推荐使用devise_parameter_sanitizer的方法,以支持&#39; .permit&#39;
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_in) do |user_params|
user_params.permit(:username, :email)
end
end