Ruby on rails 通过Rails访问多个上的附加值

Ruby on rails 通过Rails访问多个上的附加值,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我在访问has_many-through上名为permission的附加参数的值时遇到了实际问题。这可能很简单。 我的3个模型是 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 :

我在访问has_many-through上名为permission的附加参数的值时遇到了实际问题。这可能很简单。 我的3个模型是

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
但是,我似乎无法正确访问它 我试过了

perm = User.find(current_user).players_users.includes(:Permission)
 if perm == "owner"
它给出了一个ActiveRecord::AssociationNotFoundError,在PlayerUser上找不到名为“权限”的关联;也许你拼错了

我也试过了

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

它给出了一个未定义的方法错误。 未定义的方法“Player”


我知道这在我的设置中很小,但无法确定它是什么。非常感谢您的帮助。

players\u用户
玩家
与用户对象关联,因此您可以通过以下方式获取结果:

current_user.players_users.pluck(:permission)
我以前用自己的代码解决过这个问题


我马上就发布,但是首先你需要重构你的控制器,电流是低效的:

#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
--

更多的方法(如果每次都将
权限
明确设置为
所有者
)是在
播放器
模型中引入一个作为默认值:

#app/models/player.rb
class Player < ActiveRecord::Base
   enum permission: [:owner, :member, :moderator] #-> defaults to :owner
end
要理解这一点,您必须记住,由于
player\u users
是一个加入关联,
ActiveRecord
将自动填充它,如果您在
current\u user
对象(
current\u user.players
)上创建一个播放器


关于提取
权限
数据,我构建了一个脚本,将权限附加到
player
对象(使用
proxy\u association.target
等):

它的工作原理与-类似,因此,虽然您无法操作数据,但它将允许您调用
@user.players.find(params[:player\u id]。permission
。除非所有操作都在内存中完成:

#app/models/user.rb
类用户{扩展玩家权限}
结束
#app/models/concerns/player_permission.rb
模块播放权限
#装载
def负载
权限。每个do |权限|

proxy\u association.target
User.find(当前用户)。players\u users.first.permission
将为您提供第一个player\u用户的权限值。如果您想要全部权限,请使用
User.find(当前用户)。players\u users.first.pulk(:permission)
如果您有问题,请回答,我们会让它工作的Hi@RichPeck,谢谢您这么详细的回答,但是它仍然会为我抛出相同的权限错误。Hi@RichPeck,所有的工作都必须从头开始,遵循惯例,一定是在从复数转换回来时犯了一个错误。是的,作为一项规则,model应该始终是单数的(在所有情况下--
ProductUser
)顺便问一下,你想让我帮你实现“代理关联”方法吗?这一切都在内存中需要稍微更改@permission=current\u user.players\u users.where(player\u id:params[:player\u id],user\u id:current\u user)。pulk(:permission)
current_user.players_users.pluck(:permission)
#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
@permission = current_user.player_users.find(@player.id).permission
#app/models/player.rb
class Player < ActiveRecord::Base
   enum permission: [:owner, :member, :moderator] #-> defaults to :owner
end
#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
#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
#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