在进行关联验证时是否可以更改is invalid
错误?
我的代码:
class Membership < ActiveRecord::Base
belongs_to :user, inverse_of: :memberships
belongs_to :team, inverse_of: :memberships
validate :user_cannot_have_same_team_name
protected
def user_cannot_have_same_team_name
if User.find(user.id).teams.map(&:name).include? team.name
errors.add :base, "Duplicate team name"
end
end
end
class User < ActiveRecord::Base
has_many :teams, through: :memberships
has_many :memberships, dependent: :destroy
# ...
end
class Team < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
has_many :thanks
validates :name, presence: true
validate do |team|
team.memberships.each do |membership|
membership.errors.full_messages.each do |message|
errors[:base] << message
end
end
end
end
使用rails console:
[1] pry(main)> team = User.first.teams.new(name: "Wat")
User Load (0.2ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
=> #<Team:0x007fc38b72dfe8 id: nil, name: "Wat", created_at: nil, updated_at: nil>
[2] pry(main)> team.save
(0.2ms) BEGIN
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
Team Load (0.3ms) SELECT `teams`.* FROM `teams` INNER JOIN `memberships` ON `teams`.`id` = `memberships`.`team_id` WHERE `memberships`.`user_id` = 1
(0.2ms) ROLLBACK
=> false
[3] pry(main)> team.errors
=> #<ActiveModel::Errors:0x007fc38b604c48
@base=#<Team:0x007fc38b72dfe8 id: nil, name: "Wat", created_at: nil, updated_at: nil>,
@messages={:memberships=>["is invalid"], :base=>["Duplicate team name"]}>
正如您所看到的,即使我设置了自定义消息,也总会出现is invalid
错误。请指教。提前谢谢。
答案 0 :(得分:0)
您最好使用ActiveRecord中的内置validations
:
class Membership < ActiveRecord::Base
belongs_to :user, inverse_of: :memberships
belongs_to :team, inverse_of: :memberships
validate :user, uniqueness : { scope: :team, message: "Duplicate Team" }
end
对于此错误,您需要对team.name
进行验证。为什么这样做可以处理Team
id
- 实际对象。团队的name
应该归因于团队对象,因此您不希望用户拥有多个团队对象(因此使用:uniqueness
验证)
-
对于您的Team
模型,您实际上可以使用inverse_of
-
class Team < ActiveRecord::Base
has_many :memberships, inverse_of: :team
end
此 应包含您尝试通过memberships
创建的所有新Team
的所有验证:
#app/views/teams/new.html.erb
<%= form_for @team do |f| %>
<%= f.errors... #-> this should have all the errors from membership %>
<% end %>