gpt4 book ai didi

ruby-on-rails-3 - has_many :through 上的 Rails 验证计数限制

转载 作者:行者123 更新时间:2023-12-02 03:54:59 25 4
gpt4 key购买 nike

我有以下模型:Team、Member、Assignment、Role

Team 模型有_many 个成员。每个成员都有_many 角色通过分配。角色分配是 Captain 和 Runner。我还使用 Member 模型安装了 devise 和 CanCan。

我需要做的是限制每个团队最多有 1 名队长和 5 名运行者。

我找到了这个 example ,它似乎在一些定制之后工作,但在更新时('teams/1/members/4/edit')。它不适用于创建('teams/1/members/new')。但是我的其他验证(验证:role_ids,:presence => true) 确实适用于更新和创建。任何帮助将不胜感激。

更新:我找到了这个 example这似乎与我的问题相似,但我似乎无法使其适用于我的应用。

问题的根源似乎在于在验证之前和期间如何执行计数(或大小)。

例如:

更新记录时...它检查一个团队中有多少运行者并返回一个计数。 (即 5)然后,当我选择要添加到成员的角色时,它会从数据库中获取已知计数(即 5)并添加建议的更改(即 1),然后运行验证检查。 (Team.find(self.team_id).members.runner.count > 5) 这工作正常,因为它返回值 6 和 6 > 5,因此建议的更新失败而不保存并给出错误。

但是当我尝试在团队中创建新成员时...它检查一个团队中有多少运行者并返回一个计数。 (即 5)然后,当我选择要添加到成员的角色时,它会从数据库中获取已知计数(即 5),然后运行验证检查 WITHOUT 将建议的更改考虑在内。这不起作用,因为它返回一个值 5 known runner 和 5 = 5 所以建议的更新通过并且新成员和角色被保存到数据库中没有错误。

成员(member)模型:

class Member < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable

attr_accessible :password, :password_confirmation, :remember_me
attr_accessible :age, :email, :first_name, :last_name, :sex, :shirt_size, :team_id, :assignments_attributes, :role_ids
belongs_to :team
has_many :assignments, :dependent => :destroy
has_many :roles, through: :assignments
accepts_nested_attributes_for :assignments

scope :runner, joins(:roles).where('roles.title = ?', "Runner")
scope :captain, joins(:roles).where('roles.title = ?', "Captain")

validate :validate_runner_count
validate :validate_captain_count
validates :role_ids, :presence => true

def validate_runner_count
if Team.find(self.team_id).members.runner.count > 5
errors.add(:role_id, 'Error - Max runner limit reached')
end
end

def validate_captain_count
if Team.find(self.team_id).members.captain.count > 1
errors.add(:role_id, 'Error - Max captain limit reached')
end
end

def has_role?(role_sym)
roles.any? { |r| r.title.underscore.to_sym == role_sym }
end

end

成员 Controller :

class MembersController < ApplicationController
load_and_authorize_resource :team
load_and_authorize_resource :member, :through => :team

before_filter :get_team
before_filter :initialize_check_boxes, :only => [:create, :update]

def get_team
@team = Team.find(params[:team_id])
end

def index
respond_to do |format|
format.html # index.html.erb
format.json { render json: @members }
end
end

def show
respond_to do |format|
format.html # show.html.erb
format.json { render json: @member }
end
end

def new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @member }
end
end

def edit

end

def create
respond_to do |format|
if @member.save
format.html { redirect_to [@team, @member], notice: 'Member was successfully created.' }
format.json { render json: [@team, @member], status: :created, location: [@team, @member] }
else
format.html { render action: "new" }
format.json { render json: @member.errors, status: :unprocessable_entity }
end
end
end

def update
respond_to do |format|
if @member.update_attributes(params[:member])
format.html { redirect_to [@team, @member], notice: 'Member was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @member.errors, status: :unprocessable_entity }
end
end
end

def destroy
@member.destroy

respond_to do |format|
format.html { redirect_to team_members_url }
format.json { head :no_content }
end
end

# Allow empty checkboxes
# http://railscasts.com/episodes/17-habtm-checkboxes
def initialize_check_boxes
params[:member][:role_ids] ||= []
end

end

_形式部分

<%= form_for [@team, @member], :html => { :class => 'form-horizontal' } do |f| %>

#...

# testing the count...
<ul>
<li>Captain - <%= Team.find(@member.team_id).members.captain.size %></li>
<li>Runner - <%= Team.find(@member.team_id).members.runner.size %></li>
<li>Driver - <%= Team.find(@member.team_id).members.driver.size %></li>
</ul>

<div class="control-group">
<div class="controls">
<%= f.fields_for :roles do %>
<%= hidden_field_tag "member[role_ids][]", nil %>
<% Role.all.each do |role| %>
<%= check_box_tag "member[role_ids][]", role.id, @member.role_ids.include?(role.id), id: dom_id(role) %>
<%= label_tag dom_id(role), role.title %>
<% end %>
<% end %>
</div>
</div>

#...
<% end %>

最佳答案

尝试

class Member < ActiveRecord::Base
...

def validate_runner_count
if self.team.members.runner.count > 5
errors.add(:role_id, 'Error - Max runner limit reached')
end
end

def validate_captain_count
if self.team.members.captain.count > 1
errors.add(:role_id, 'Error - Max captain limit reached')
end
end
end

关于ruby-on-rails-3 - has_many :through 上的 Rails 验证计数限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13094227/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com