基本上我有用户通过使用设计宝石注册自己的应用程序。 我没有像(电子邮件,密码)这样的标准注册表单,而是总共使用了(名称,contact_nr,电子邮件,密码,密码_确认)字段,的额外2个字段(名称,contact_nr) :name和:contact_nr属性存在于' clients'仅限表格。
Table name: clients
id :integer not null, primary key,
name :string(255)
surname :string(255)
contact_nr :string(255)
user_id :integer
class Client < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :client, dependent: :destroy
after_create :update_user_client
def name
return unless client
client.name
end
def contact_nr
return unless client
client.contact_nr
end
def update_user_client
Client.last.update_attributes(user: self)
end
end
在我的RegistrationsController中,我只有一个方法
class RegistrationsController < Devise::RegistrationsController
before_action :create_client
private
def create_client
return if params[:user].blank?
Client
.new(name: params[:user][:name],
contact_nr: params[:user][:contact_nr])
.save(validate: false)
end
end
困扰我的是那种编写代码,感觉就像代码味道。 你会如何实现它? 谢谢你们期待你们的答案..
答案 0 :(得分:1)
如果您现在没有正当理由和/或要求,我可以提供的第一条建议是不要将客户和用户分成两个表。这会让事情变得更容易。
如果您有正当理由,请参阅以下有关如何改善此代码段现有状态的建议:
params[:user].blank?
检查,您应该使用Devise的方式执行此操作,并在before_action回调中提供继承的方法devise_parameter_sanitizer.permit
。accepts_nested_attributes_for :client
。before_save
回调,以便您可以将用户的名称属性传递给客户端。after_create
回调非常危险,因为它不是原子保存(不保证客户端在更新用户记录后会更新)。所以不要使用它。 accepts_nested_attributes_for
将处理创建和更新通话。contact_nr
和name
属性,请在其中使用delegate
方法。总而言之,我会重构那段代码:
class User < ActiveRecord::Base
has_one :client, dependent: :destroy
accept_nested_attributes_for :client
delegate :name, to: :client
delegate :contact_nr, to: :client
# optional. if you want to keep name attr in both models.
before_save :sync_names
private
def sync_names
self.client.name = name if client.present?
end
end
class RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters
protected
def configure_permitted_parameters
added_attrs = [:name, :email, :password, :password_confirmation, client_attributes: [:contact_nr]]
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
devise_parameter_sanitizer.permit :account_update, keys: added_attrs
end
end
不要忘记更新您的注册和帐户更新表单以接受客户端资源的嵌套属性。
答案 1 :(得分:0)
如果您使用JS验证数据并使用 params.require(:client).permit 进行过滤,则代码看起来很好。尝试在Rspec中创建许多不同的场景。测试通常会发现意外的缺陷。