Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails手动提交记录_Ruby On Rails - Fatal编程技术网

Ruby on rails Rails手动提交记录

Ruby on rails Rails手动提交记录,ruby-on-rails,Ruby On Rails,我正在尝试使用Rails构建一个2人回合制的小游戏,要初始化游戏,只需要1名玩家设置场地,然后其他玩家就可以加入。游戏中的每个玩家将拥有一块可以容纳建筑物的土地,它们之间的关系如下: #Game has_many :lands #Land belongs_to :game has_many :buildings #Building belongs_to :game 只有游戏有一个控制器,因为它是所有控制器的主人,所以当游戏被初始化时,请求将包含创建土地和建筑物的信息,所有这些都被视为一个,所以

我正在尝试使用Rails构建一个2人回合制的小游戏,要初始化游戏,只需要1名玩家设置场地,然后其他玩家就可以加入。游戏中的每个玩家将拥有一块可以容纳建筑物的土地,它们之间的关系如下:

#Game
has_many :lands
#Land
belongs_to :game
has_many :buildings
#Building
belongs_to :game
只有游戏有一个控制器,因为它是所有控制器的主人,所以当游戏被初始化时,请求将包含创建土地和建筑物的信息,所有这些都被视为一个,所以如果其中一个记录失败,我不想提交任何内容。我曾想过使用
building.save if land.save
,但它会产生错误,因为我正在将建筑保存到一块不退出的土地上,但如果我先保存了土地,建筑失败,那么我需要删除土地和游戏,要处理所有这些情况,多个建筑物的运行和来自多个地方的各种错误会变得复杂

我还可以使用哪些其他选项来实现此目的

编辑: 游戏控制器将如下所示:

class GamesController < ApplicationController
  def create
    #generate new land to contain buildings
    land = Land.new(user: @current_user)
    #generate new buildings from array of hashes, contains coords+land_id
    buildings = []
    params[:buildings].each do |building|
      buildings.push Building.new(building.merge!({land: land}))
    end
    game = Game.new(user_1: @current_user, land_1: land)
    land.game = game #set the game it belongs to
    #some code here to save land+game+buildings
    #if one of them failed then nothing is saved at all.
  end
end
class GamesController

还有一个问题,我不能像这样保存游戏,因为它验证了土地的存在,也不能保存土地,因为它验证了游戏的存在,同样的,建筑物也验证了土地的存在。因此,我需要一个代码,它可以一次性保存它们,并且仍然能够成功地验证它们。

您可以将查询包装到事务中:

ActiveRecord::Base.transaction do
  # put your calls here
end

您应该使用
.save在Rails中,您可以使用
接受
的嵌套属性来从同一表单创建嵌套模型:

class User < ActiveRecord::Base
  has_many :pets
  accepts_nested_attributes_for :pets
  validates_associated :pet
end

class UserController < ApplicationController

  def new
    @user = User.new
    @user.pets.build 
  end

  def create
    @user
  end

  def pet_params
    params.require(:user).permit(pets_attributes: [:name, :type])
  end
end
class用户
您还可以使用事务将记录插入数据库,并在以后的条件失败时回滚

class OrdersController < ApplicationController
  def create
    @order = Order.new(order_params)

    Order.transaction do
       @payment = Payment.new(customer: @order.customer, amount: order.amount)
       raise ActiveRecord::Rollback unless @order.save && @payment.save
    end
  end
end
class OrdersController
但更重要的是,不要试图在一个控制器动作中完成所有操作。它会导致非常脆弱和过于复杂的设计

相反,您可能需要分几个步骤进行游戏设置

  • 用户1创建游戏
    POST/games
  • 用户1被重定向到
    GET/games/1
  • 由于没有土地,用户1将通过填写表格创建土地,并将其发布到
    /games/1/lands
    。然后他被重定向回
    /games/1
  • 用户现在可以在游戏视图中看到我们刚刚创建的土地
  • 用户1决定在土地1上建造一个猪圈。他按下按钮,发送一个
    POST/lands/1/buildings
    。但是用户1没有足够的资源,因此生成的验证失败。我们向用户显示错误消息

  • 正如您可能已经猜到的那样,浏览器游戏设计需要大量使用ajax和javascript。构建服务器端API只是一小部分。

    您能在这里添加一些实际代码吗?它比你试图描述你的控制器中发生的事情更容易阅读。我还没有写游戏控制器,这就是我一直在研究如何编写它以实现上面提到的目标的地方,我将尝试用一个通用的形式更新我认为它将如何出现。那么你认为你可以重新表述你的问题吗?听起来好像你在寻找交易,但我只能理解问题的1/10。查看和。我如何限制
    require
    permit
    中的嵌套属性,就像在普通强参数中一样?我将对此进行研究,这将在没有错误的情况下验证所有记录?没有任何事务类似于数据库中的撤消功能。您可以执行多个SQL语句,然后在任何时候回滚(撤消),直到提交事务。您可以将其与验证一起使用,但它们实际上是独立的概念。我正在研究嵌套属性,它似乎是与事务相结合的最佳解决方案。我不想使用多个步骤,因为不允许用户编辑他创建的游戏,也不允许在游戏期间编辑。