2013-08-01 122 views
0

這是我的代碼。營救活動記錄:記錄無效

class Product < ActiveRecord::Base 
attr_accessible :name, :price, :released_on 
begin 
    validates :name, uniqueness: true 
    rescue ActiveRecord::RecordInvalid => e 
    render(inline: "RESCUED ActiveRecord::RecordInvalid") 
    return 
end 
def self.to_csv(options = {}) 
CSV.generate(options) do |csv| 
    csv << column_names 
    all.each do |product| 
    csv << product.attributes.values_at(*column_names) 
    end 
end 
end 



def self.import(file) 
CSV.foreach(file.path , headers:true) do |row| 
Product.create! row.to_hash # If we want to add a new item 

end 
end 
end 

當我保存有相同名稱的重複模式將引發異常

的ActiveRecord :: RecordInvalid中的ProductsController#進口

Validation failed: Name has already been taken 

Rails.root: /home/deepender/396-importing-csv-and-excel/store-before 

我使用的救援行動還在它是不是處理錯誤?任何猜測,我錯了。

回答

5

夫婦的事情。您不會將validates包裝在begin/rescue區塊中。所以你的模型應該只是這樣的:

class Product < ActiveRecord::Base 
    attr_accessible :name, :price, :released_on 
    validates :name, uniqueness: true 
end 

它在控制器中執行驗證並適當地處理它。樣本控制器可能類似於:

class ProductsController < ApplicationController 
    def create 
    @product = Product.new(params[:product]) 
    if @product.valid? 
     @product.save 
     flash[:notice] = "Product created!" 
     redirect_to(@product) and return 
    else 
     render(:action => :new) 
    end 
    end 
end 

,然後在視圖中您可能使實際的錯誤返回給用戶:

# app/views/products/new.html.erb 

<%= error_messages_for(@product) %> 
.. rest of HTML here .. 

error_messages_for不再包含在Rails的默認和它在寶石dynamic_form

爲了顯示錯誤的一般方法看到的Rails指南:

http://guides.rubyonrails.org/active_record_validations.html#displaying-validation-errors-in-views

+0

其實我的控制器沒有創建方法,基本上在這個應用程序,我導入CSV文件,並創建一個數據庫。請參閱上面的更新代碼。 –

3

正如Cody提到的那樣,不要在開始/救援中包裝你的valites,因爲validates方法只是告訴你的模型什麼需要驗證,而不是真正的驗證方法運行的地方。

然後,這裏是你的導入方法應該是什麼樣子:

def import(file) 
    CSV.foreach(file.path , headers:true) do |row| 
    product = Product.new(row.to_hash) 

    if product.save 
    # product valid and created 
    else 
    # invalid record here... you can inspect product.errors 
    end 

end 
+0

謝謝,我得到了一個錯誤,說沒有定義渲染方法。 def self.import(file) CSV.foreach(file.path,headers:true)do | row | @ product = Product.new(row.to_hash) if @ product.valid? @ product.save flash [:notice] =「產品創建!」 redirect_to時(@product),並返回 其他 渲染(:動作=>:指數) 結束 結束 結束 –

+2

是的,它看起來像你只是把我的控制器代碼,一屁股就到你的代碼。我的代碼的上下文是一個Rails控制器,它具有'redirect','render','flash'。您不在控制器內運行,因此您無法訪問這些方法。退後一步,思考我們寫的是什麼以及你的背景是什麼。看起來你沒有看到更大的圖像。 –

+0

是的。事實上,您可以刪除我的代碼中的if部分,然後寫入product.save然後,在您接收文件或w/e的控制器中,您需要調用Product.import(file_uploaded)並在那裏呈現根據該調用的結果 –