2015-12-15 125 views
0

在进行关联验证时是否可以更改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控制台:

[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"]}> 

正如你所看到的,总会有即使我已经把我的自定义mesage is invalid错误。请指教。先谢谢你。

回答

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。为什么这样做,当你可以处理Teamid的 - 实际的对象。球队的name应归因于团队对象,所以你不希望用户拥有多个团队对象(因此使用了:uniqueness验证)

-

为了您Team模型,您可以通过实际使用模型拉动相关验证inverse_of -

class Team < ActiveRecord::Base 
    has_many :memberships, inverse_of: :team 
end 

应该包括任何新所有的验证你想通过你的Team创建:

#app/views/teams/new.html.erb 
<%= form_for @team do |f| %> 
    <%= f.errors... #-> this should have all the errors from membership %> 
<% end %> 
+0

纠正我,如果我错了,但您的验证仍然允许用户创建一个团队使用相同的名称?例如,用户A应该能够创建一个名称设置为Team1的团队。之后,他不能再创建一个名字为Team1的团队。我试过在'rails console'中使用相同的命令,这次它只是通过了 – RubyCat