ruby-on-rails – Rails – CanCan HABTM关联检查
我的模型设置如下(联系人中的自我关联,因为我想为经销商存储的信息镜像该表中的所有字段,似乎与DRY保持一致以使用现有的数据结构):
class Contact < ActiveRecord::Base attr_accessible :reseller_id has_and_belongs_to_many :users has_many :reseller_clients,:class_name => "Contact",:foreign_key => "reseller_id" belongs_to :reseller,:class_name => "Contact" end class User < ActiveRecord::Base attr:accessible :name has_and_belongs_to_many :contacts end 使用cancan,我想拥有一个能够管理自己联系的经销商登录.用户和经销商之间的映射是HABTM,因此可以通过以下方式实现:manage Contact,:users => {:id => user.id}如下. 我还希望经销商登录能够在以下逻辑中管理与managed_accounts描述的集合匹配的所有Contact: reseller_contacts = user.contacts managed_accounts = [] reseller_contacts.each do |i| managed_accounts << i.reseller_clients end managed_accounts.flatten! 我目前的能力课程有: class Ability include CanCan::Ability def initialize(user) if user.role? :reseller # Allow resellers to manage their own Contact can :manage,Contact,:users => {:id => user.id} # This works correctly at present # Allow resellers to manage their client Contacts can :manage,:reseller => {:users => {:id => user.id}} #This doesn't work end end end 我收到它的错误如下: Mysql2::Error: Unknown column 'contacts.users' in 'where clause': SELECT `contacts`.* FROM `contacts` INNER JOIN `contacts` `resellers_contacts` ON `resellers_contacts`.`id` = `contacts`.`reseller_id` INNER JOIN `contacts_users` ON `contacts_users`.`contact_id` = `resellers_contacts`.`id` INNER JOIN `users` ON `users`.`id` = `contacts_users`.`user_id` INNER JOIN `contacts_users` `users_contacts_join` ON `users_contacts_join`.`contact_id` = `contacts`.`id` INNER JOIN `users` `users_contacts` ON `users_contacts`.`id` = `users_contacts_join`.`user_id` WHERE ((`contacts`.`users` = '---n:id: 6n') OR (`users`.`id` = 6)) 我对cancan的理解是它根据每个联系人检查什么是允许的和不允许的.如果我可以在一个块中执行我想要的操作,它将显示如下(涵盖经销商自己的联系人和所有经销商客户的联系人): can :manage,Contact do |contact| user.contacts.exists?(contact.reseller_id) || user.contacts.exists?(contact.id) end 我不能使用块,因为当我在控制器上的索引操作中尝试使用@contacts = Contact.accessible_by(current_ability)时,我得到: The accessible_by call cannot be used with a block 'can' definition. The SQL cannot be determined for :index Contact(id: integer,first_name: string,last_name: string,postal_addr_line_1: string,postal_addr_line_2: string,postal_addr_line_3: string,postal_addr_city: string,postal_addr_post_code: string,postal_addr_country: string,billing_addr_line_1: string,billing_addr_line_2: string,billing_addr_line_3: string,billing_addr_city: string,billing_addr_post_code: string,billing_addr_country: string,contact_email: string,company_name: string,phone_home: string,phone_work: string,phone_mobile: string,split_bills: boolean,created_at: datetime,updated_at: datetime,reseller_id: integer) 编辑: 几乎已经解决了,现在我只是遇到了一个组合能力的问题: 我将Ability模型的工作部分改为: reseller_contacts = user.contacts managed_accounts = [] reseller_contacts.each do |i| i.reseller_clients.each do |rc| managed_accounts << rc.id end end can :manage,:id => managed_accounts can :manage,:users => {:id => user.id} can :create,Contact 现在唯一的问题是第一个问题:管理线被第二个覆盖.我的印象是它们应该是添加剂,而不是替代品.需要更多的研究,但我认为这个问题本身是由上述问题解决的.现在我需要弄清楚如何使两者都可以:管理行应用. 解决方法
编辑2015-03-26
注意到这个问题/答案得到了一些关注,我想我应该指出一个我以后发现的更好的方法. 创建has_one / has_many关联时,rails分别创建foreign_model_id / foreign_model_ids方法.这些方法分别返回整数或整数数组. 这意味着,而不是下面的答案,才能简化ability.rb文件中的条目,而不必使用那个丑陋的逻辑来创建我自己的对象数组并迭代它们: 可以:manage,contact,id:(user.contact_ids user.reseller_client_ids) 以前的答案留给后代 通过在我的Ability.rb文件中使用它来修复: # Manage all contacts associated to this reseller reseller_contacts = user.contacts managed_contacts = [] reseller_contacts.each do |i| i.reseller_clients.each do |rc| managed_contacts << rc.id end managed_contacts << i.id end can :manage,:id => managed_contacts Deefour,谢谢你一路走来的帮助,如果没有你的意见,我不认为我会去那里. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |