通过Rails访问has_many上的其他值

时间:2016-01-30 09:02:55

标签: ruby-on-rails activerecord

我在访问has_many通过的名为权限的附加参数的值时遇到了麻烦。这可能很简单。 我的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

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

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,名为&#39; Permission&#39;在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)

这给出了未定义的方法错误。 未定义的方法`播放器&#39;

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

2 个答案:

答案 0 :(得分:1)

if cmd in [None, 'hi']: print('command "hi"') players_users与User对象相关联,因此您可以将结果提取为,

players

答案 1 :(得分: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

要访问permission的{​​{1}},您需要使用以下内容:

player_user

-

更多DRY方法(如果您每次明确将@permission = current_user.player_users.find(@player.id).permission 设置为permission)将在owner中引入enum模型作为默认值:

Player

这将取消必须在#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)。

Association Extensions

关于提取current_user.players数据,我构建了一个脚本,将权限附加到permission对象(使用player等):

proxy_association.target

它与SQL Alias column的工作方式类似 - 所以当你无法操纵数据时,它会允许你调用#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 ..除了它已经在内存中完成 : / p>

@user.players.find(params[:player_id].permission

-

顺便说一句,convention是保留#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 model singularProductUser)的所有方面。