2016-01-30 20 views
2

我在通过访问has_many上的一个额外参数的权限时遇到了麻烦。这可能很简单。 我的3款机型均通过Rails在has_many上访问其他值

class User < ActiveRecord::Base 
    has_many :players_users 
    has_many :players, through: :players_users 
end 
class Player < ActiveRecord::Base 
    has_many :players_users 
    has_many :users, through: :players_users 
end 
class PlayersUser < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :player 
    validates :player_id, uniqueness: { scope: :user_id } 
end 

我控制器保存记录没有问题。将权限值添加到正确的连接表。

def create 
    @players = Player.new(players_params) 
    @user= current_user 
    if @players.save 
     @player = Player.last 
     @user.save && @user.players_users.create(:player_id =>@player.id, :permission =>"owner") 
     redirect_to '/players' 
    else 
     render 'new' 
    end 
    end 

但是我似乎无法正常访问 我试图

perm = User.find(current_user).players_users.includes(:Permission) 
if perm == "owner" 

其中给出一个ActiveRecord :: AssociationNotFoundError,在PlayersUser没有被发现命名为“许可”关联;也许你拼错了吗?

我也曾尝试

perm = User.players_users.where(player_id = @player.id && user_id = current_user) 
perm.permission 

perm = User.Player.where(player_id = @player.id && user_id = current_user) 

perm = User.players.where(player_id = @player.id && user_id = current_user) 

其中给出一个未定义的方法错误。 undefined方法`玩家'

我知道这是在我的设置很小,但无法弄清楚它是什么。任何帮助赞赏。

+1

'User.find(current_user).players_users.first.permission'会给你第一个player_user的权限值。如果你想全部使用'User.find(current_user).players_users.first.pluck(:permission)' –

回答

1

players_usersplayers与用户对象关联,这样你就可以获取结果,

current_user.players_users.pluck(:permission) 
+0

必须稍微改变@permission = current_user.players_users.where(player_id:params [:player_id],user_id:current_user ).pluck(:permission) – user1957774

1

我已经解决了这个issue之前,我自己的代码。


我会后,在第二,但首先你需要重构你的控制器,电流效率低:

#app/controllers/players_controller.rb 
class PlayersController < ApplicationController 
    def create 
     @player = current_user.players.new players_params 
     if @player.save 
      current_user.player_users.find(@player.id).update(permission: "owner") 
      redirect_to players_path 
     end 
    end 

    private 

    def player_params 
     params.require(:player).permit(....) 
    end 
end 

要访问player_userpermission,你需要使用下面的:

@permission = current_user.player_users.find(@player.id).permission 

-

阿多米矿DRY方法(如果你明确设置permission为每次owner)将引入enumPlayer模式作为默认:

#app/models/player.rb 
class Player < ActiveRecord::Base 
    enum permission: [:owner, :member, :moderator] #-> defaults to :owner 
end 

这将有定义permission在做掉该create方法(当然,除非你想改变它):

#app/controllers/players_controller.rb 
class PlayersController < ApplicationController 
    def create 
     @player = current_user.players.new players_params 
     redirect_to players_path if @player.save 
    end 
end 

要理解这一点,你必须记住,因为player_users加入协会,ActiveRecord将自动填充它,如果您在current_user对象(current_user.players)上创建播放器。


Association Extensions

至于拉动permission数据,我建了一个脚本,追加许可的player对象(使用proxy_association.target等):

#current 
@player  = current_user.players.find params[:player_id] 
@permission = current_user.player_users.find(params[:player_id]).permission 

#script 
@player  = current_user.players.find params[:player_id] 
@permission = @player.permission 

它的工作原理类似于一个SQL Alias column - 所以虽然你不能操纵数据,它将允许你呼叫@user.players.find(params[:player_id].permission ..除了它的全部完成在内存中

#app/models/user.rb 
class User < ActiveRecord::Base 
    has_many :player_users 
    has_many :players, through: :player_users, -> { extending PlayerPermission } 
end 

#app/models/concerns/player_permission.rb 
module PlayerPermission 

     #Load 
     def load 
      permissions.each do |permission| 
       proxy_association.target << permission 
      end 
     end 

     #Private 
     private 

     #Permissions 
     def permissions 
      return_array = [] 
      through_collection.each_with_index do |through,i| 
       associate = through.send(reflection_name) 
       associate.assign_attributes({permission: items[i]}) 
       return_array.concat Array.new(1).fill(associate) 
      end 
      return_array 
     end 

     ####################### 
     #  Variables  # 
     ####################### 

     #Association 
     def reflection_name 
      proxy_association.source_reflection.name 
     end 

     #Foreign Key 
     def through_source_key 
      proxy_association.reflection.source_reflection.foreign_key 
     end 

     #Primary Key 
     def through_primary_key 
      proxy_association.reflection.through_reflection.active_record_primary_key 
     end 

     #Through Name 
     def through_name 
      proxy_association.reflection.through_reflection.name 
     end 

     #Through 
     def through_collection 
      proxy_association.owner.send through_name 
     end 

     #Captions 
     def items 
      through_collection.map(&:permission) 
     end 

     #Target 
     def target_collection 
      #load_target 
      proxy_association.target 
     end 

end 

-

顺便说一句,convention是保持一个modelsingularProductUser)的所有方面。

+0

如果您遇到问题,请回复,我们会立即开始工作 –

+0

Hi @RichPeck,感谢您的详细解答,但它仍然为我带来了相同的权限错误。 – user1957774

+0

请求的权限错误? –