问题 1:ruby 的方法参数数量不对不是会报错的吗? 问题 2:方法调用时最后的参数中 :if => 是什么意思?
以下是 safe_attributes 方法的调用
safe_attributes 'status_id',
'assigned_to_id',
'fixed_version_id',
'done_ratio',
'lock_version',
'notes',
:if => lambda {|issue, user| issue.new_statuses_allowed_to(user).any? }
safe_attributes 'notes',
:if => lambda {|issue, user| user.allowed_to?(:add_issue_notes, issue.project)}
以下是 safe_attributes 方法的定义
# Safely sets attributes
# Should be called from controllers instead of #attributes=
# attr_accessible is too rough because we still want things like
# Issue.new(:project => foo) to work
def safe_attributes=(attrs, user=User.current)
return unless attrs.is_a?(Hash)
attrs = attrs.dup
# Project and Tracker must be set before since new_statuses_allowed_to depends on it.
if (p = attrs.delete('project_id')) && safe_attribute?('project_id')
if allowed_target_projects(user).where(:id => p.to_i).exists?
self.project_id = p
end
end
if (t = attrs.delete('tracker_id')) && safe_attribute?('tracker_id')
self.tracker_id = t
end
if (s = attrs.delete('status_id')) && safe_attribute?('status_id')
if new_statuses_allowed_to(user).collect(&:id).include?(s.to_i)
self.status_id = s
end
end
attrs = delete_unsafe_attributes(attrs, user)
return if attrs.empty?
unless leaf?
attrs.reject! {|k,v| %w(priority_id done_ratio start_date due_date estimated_hours).include?(k)}
end
if attrs['parent_issue_id'].present?
s = attrs['parent_issue_id'].to_s
unless (m = s.match(%r{\A#?(\d+)\z})) && (m[1] == parent_id.to_s || Issue.visible(user).exists?(m[1]))
@invalid_parent_issue_id = attrs.delete('parent_issue_id')
end
end
if attrs['custom_field_values'].present?
editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s}
# TODO: use #select when ruby1.8 support is dropped
attrs['custom_field_values'] = attrs['custom_field_values'].reject {|k, v| !editable_custom_field_ids.include?(k.to_s)}
end
if attrs['custom_fields'].present?
editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s}
# TODO: use #select when ruby1.8 support is dropped
attrs['custom_fields'] = attrs['custom_fields'].reject {|c| !editable_custom_field_ids.include?(c['id'].to_s)}
end
# mass-assignment security bypass
assign_attributes attrs, :without_protection => true
end