2015-07-11 84 views
1

我正在嘗試使用Rails構建一個小型2人回合制遊戲,初始化遊戲時只需要1名玩家設置該字段,然後另一名玩家可以加入。在遊戲中的每個玩家都會有,它可以包含建築物的土地,如下它們之間的關係:Rails手動提交記錄

#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 

還有,我救不了這樣的比賽,因爲它證明了土地的存在,並不能節約土地的問題,因爲它驗證遊戲的存在,同樣適用於他們驗證土地存在的建築物。所以我需要一個能夠一次性保存它們的代碼,並且仍然能夠成功驗證它們。

+0

你能在這裏添加一些實際的代碼嗎?它比你試圖描述你的控制器中發生了什麼更容易閱讀。 – max

+0

我還沒有編寫遊戲控制器,這是我堅持如何寫在一個方式來實現所提到的,我會嘗試用一般形式更新我如何認爲它會出現。 –

+0

你認爲你可以改變你的問題嗎?這聽起來像是你正在尋找交易,然後我再次只能理解問題的1/10。 – max

回答

0

你可以用查詢在交易:

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

而且你應該使用.save!方法,使通過驗證的創建異常拋出,否則查詢失敗默默。

+0

我會看看這個,這將驗證所有記錄沒有錯誤? –

+0

沒有事務就像數據庫中的撤消功能。您可以執行多個SQL語句,然後在任何時候回滾(撤消),直到事務提交。您可以將它與驗證一起使用,但它們實際上是分開的概念。 – max

0

在Rails可以使用accepts_nested_attributes_for從相同的形式創建嵌套模式:

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

但更重要的是不要試圖在一個控制器操作中做所有事情。它導致非常脆弱和過於複雜的設計。

相反,您可能需要在多個步驟中完成遊戲設置。

  1. 用戶1創建遊戲POST /games
  2. 用戶1被重定向到GET /games/1
  3. 由於沒有陸地用戶1將通過在形式和職位,以/games/1/lands填充創建的土地。然後他被重定向回/games/1
  4. 用戶現在可以看到我們剛剛在遊戲視圖中創建的土地。
  5. 用戶1決定在Land 1中建立一個豬筆。他按下發送一個POST /lands/1/buildings的按鈕。但用戶1沒有足夠的資源,因此對於構建的驗證失敗。我們向用戶顯示錯誤消息。

正如您可能猜到的一樣 - 瀏覽器遊戲設計需要廣泛使用ajax和javascript。構建服務器端API只是一小部分。

+0

我正在研究嵌套屬性,它似乎是與事務結合的最佳解決方案。 我不想使用多個步驟,因爲用戶不允許編輯他創建的遊戲並在遊戲過程中阻止編輯。 –