2010-04-01 21 views
2

目前我的控制器允許用戶一次提交多個「鏈接」。它將它們收集到一個數組中,爲該用戶創建它們,但捕獲用戶返回並修復的任何錯誤。我怎樣才能忽略該用戶已有的任何鏈接的創建?我知道我可以爲該用戶使用validates_uniqueness_of作用域,但我寧願完全忽略它們的創建。這裏是我的控制器:如果存在,我該如何拒絕?爲非嵌套屬性?

@links = PARAMS [:鏈接] .values.collect {|友情鏈接| current_user.links.create(鏈接) } .reject {| p | p.errors.empty? }

每個鏈接都有一個url,所以我想過檢查該用戶是否已經存在link.url,但並不確定如何或在哪裏做到這一點。我應該以何種方式將它粘貼到我的控制器上?還是應該是模型中的新方法,例如before_validation回調? (注意:這些「鏈接」不是嵌套的,但它們屬於用戶。)

所以,我想只是可以忽略這些鏈接的創建。就像用戶提交了5個鏈接,但其中2個已經存在,那麼我只想讓這2個被忽略,而其他3個被創建。我應該如何去做這件事?

編輯:感謝Kandada,我現在用這個:

@links = PARAMS [:鏈接] .values.collect.reject { |友情鏈接| current_user.links.exists?(:url => link [:url])}

@links = @ links.collect {| link | current_user.links.create(鏈接) } .reject {| p | p.errors.empty? }

所以我把兩者分開,首先檢查是否存在任何存在,然後創建那些沒有被拒絕的。有沒有更好的方法來做到這一點,比如也許結合這兩個語句會提高性能?如果不是,我覺得我很滿意。 (再次感謝你Kandada和j)

回答

2

試試這個:

@links = current_user.links.create(params[:links].reject{ |link| 
      current_user.links.exists?(:url=>link[:url]) }) 

或者,你可以在Link模型添加一個唯一性檢查爲url屬性。

class Link 
    validates_uniqueness_of :url, :scope => [:user_id] 
end 

在你的控制器:

@links = current_user.links.create(params[:links]) 

返回的結果集是新創建的Link對象的數組。任何與現有鏈接匹配的鏈接都將被忽略。

編輯

這裏是另一種方式在一個通做到這一點。

@links = params[:links].map{|link| 
      !current_user.links.exists?(:url=> link[:url]) and 
      current_user.links.create(link)}.select{|link| link and 
       link.errors.empty?} 

我仍然認爲你應該拿到之後你獨特的驗證工作,並使用此代碼:

@links = current_user.links.create(params[:links]).select{|link| 
      link.errors.empty?} 

在後一種方法的獨特性驗證模型來完成。這確保了鏈接url的唯一性,無論鏈接是如何創建的。

+0

嗨,Kandada,謝謝。 嘗試你的第一個代碼,我得到一個未定義的方法'網址'的數組。並嘗試第二種方式,使用validates_uniqueness_of:url,:scope =>:user_id(我在用戶範圍中添加),我得到一個NoMethodError,私人方法'gsub'調用,這是我做after_validation。所以,我不確定有什麼問題。 – GoodGets 2010-04-01 19:45:18

+0

修復了第一個選項中的錯誤。再試一次。爲了幫助我完成第二部分,我需要查看模型代碼。將貼子(http://pastie.org/)鏈接到代碼。 – 2010-04-01 21:05:26

+0

沒有必要。那樣做了。非常感謝Kandada。 我實際上通過計算兩次@links來解決它。一旦看到它們是否存在,那麼對於那些沒有被拒絕的人來說也是如此。 (我將解決方案代碼添加到問題中,以防萬一你知道更好的方法)。謝謝你,Kandada。 – GoodGets 2010-04-02 02:25:15

1

拒絕存在的鏈接之前創建它們:

new_links = params[:links].reject{ |link| current_user.links.exists?(link) } 

Somethink這樣。不知道這碼...

+0

謝謝j。這正是我的想法,但無法弄清楚如何使它適合我的控制器。是否可以有2個「拒絕」呼叫同樣的聲明,還是應該以某種方式將它們分開? – GoodGets 2010-04-01 19:49:10

+0

你需要另一個'拒絕'在哪裏? – 2010-04-01 19:56:58

+0

,因爲我已經拒絕那些沒有通過驗證的人。有沒有比在控制器中使用代碼更好的方法? – GoodGets 2010-04-02 02:21:41