Ruby on rails Rails手动提交记录
我正在尝试使用Rails构建一个2人回合制的小游戏,要初始化游戏,只需要1名玩家设置场地,然后其他玩家就可以加入。游戏中的每个玩家将拥有一块可以容纳建筑物的土地,它们之间的关系如下: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 只有游戏有一个控制器,因为它是所有控制器的主人,所以当游戏被初始化时,请求将包含创建土地和建筑物的信息,所有这些都被视为一个,所以
#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语句,然后在任何时候回滚(撤消),直到提交事务。您可以将其与验证一起使用,但它们实际上是独立的概念。我正在研究嵌套属性,它似乎是与事务相结合的最佳解决方案。我不想使用多个步骤,因为不允许用户编辑他创建的游戏,也不允许在游戏期间编辑。