Rails:在控制器中回调以在数据库中将属性从true更改为false

时间:2016-04-27 11:01:51

标签: ruby-on-rails

所以我正在测试如何制作多人Tic Tac Toe游戏,为此我制作了一个用户模型和一个游戏模型,并通过has_many_through关联他们有各种game_users。

每个游戏都有一个属性:“seeking_players”,默认情况下为true。当我创建一个新的game_user时,我会检查它们是否存在一个seek_players属性设置为true的游戏。如果存在这样的游戏,我为这个游戏制作一个新的game_user,我想将此属性设置为false。

但无论我尝试什么,我似乎都无法改变这个属性。所以,我的问题:这段代码出了什么问题:编辑:这是根据@МалъСкрылевъ的建议后的新工作代码

class GamesController < ApplicationController
  before_action :logged_in_user
  before_action :assign_game, only: [:new]

  def new
    @game.game_users.create(user: current_user)
    update_seeking_players
    redirect_to game_url(id: @game.id)
  end

  def game
    @game = Game.find_by_id(params[:id])
  end

  private

  def assign_game
    @game = Game.find_by_seeking_players(true) || Game.create
  end

  def update_seeking_players
    if @game.users.size == 2
      @game.update_attributes(seeking_players: false)
    end
  end

end

PS:我也尝试在游戏模型中改变这个“寻找玩家”属性(回调“after_add”),这可能是一个更合适的地方?但我真的无法弄清楚如何做到这一点......

更新:

这些是Game&amp; GameUser模型

class Game < ActiveRecord::Base
    has_many :game_users
    has_many :users, :through => :game_users

end

class GameUser < ActiveRecord::Base
    belongs_to :game
    belongs_to :user
    validates :game_id, presence: true
    validates :user_id, presence: true

end

更新2 seek_players的迁移

class AddSeekingPlayersWithIndexToGames < ActiveRecord::Migration
  def change
    add_column :games, :seeking_players, :boolean, :default => true
    add_index :games, :seeking_players
  end
end

1 个答案:

答案 0 :(得分:0)

我看到了控制器的一些问题。

  1. 似乎gameRequest不是new之类的真实动作名称,因此请将其替换为真实动作。

  2. 尽量不要在变量和方法的名称中使用驼峰式(或类似的),因为它会降低代码的可理解性。

  3. 所以我建议你改变控制器如下:

    class GamesController < ApplicationController
       before_action :logged_in_user
       before_action :assign_game, only: [:new]
    
       def new
          @game.game_users.create(user: current_user)
          update_seeking_players
    
          redirect_to game_url(@game)
       end
    
       def game
       end
    
       private
    
       def assign_game
          @game = Game.find_by_seeking_players(true) || Game.create
       end
    
       def update_seeking_players
          if @game.users.size == 2
             @game.update(seeking_players: false)
          end
       end
    
    end
    

    所以,如果seeking_players是一个真正的列,它必须是,所以删除attr_accessor,因为它阻止访问db列:

    class Game < ActiveRecord::Base
       has_many :game_users
       has_many :users, :through => :game_users
    end