2016-01-30 65 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

請求的權限錯誤? –