2013-07-19 49 views
0

我使用rails構建REST API,並且我有幾個接受嵌套和遞歸JSON的控制器,例如,在/taxonomies/:id.json上執行PUT時,您可以傳遞類似:嵌套和遞歸JSON輸入處理

{ 
    "names":[ 
    "brands", 
    "secondary_brands" 
    ], 
    "taxonomy_data":{ 
    "some":"data" 
    }, 
    "terms":[ 
    { 
     "slug":"apple", 
     "data":{ 
     "value":"Apple California" 
     }, 
     "overridable_data":{ 
     "weight":0.5 
     }, 
     "term_data":{ 
     "description":{ 
      "en":"Apple makes the iPhone" 
     } 
     } 
    }, 
    { 
     "slug":"microsoft", 
     "data":{ 
     "value":"Microsoft Inc" 
     }, 
     "overridable_data":{ 
     "weight":0.5 
     }, 
     "term_data":{ 
     "description":{ 
      "en":"Microsoft makes windows" 
     } 
     }, 
     "children":[ 
     { 
      "data":{ 
      "value":"Xbox" 
      }, 
      "overridable_data":{ 
      "weight":0.5 
      }, 
      "term_data":{ 
      "description":{ 
       "en":"Xbox one is bad" 
      } 
      } 
     } 
     ] 
    }, 
    { 
     "slug":"hp", 
     "data":{ 
     "value":"HP Inc" 
     }, 
     "overridable_data":{ 
     "weight":0.5 
     }, 
     "term_data":{ 
     "description":{ 
      "en":"HP makes atomic clocks" 
     } 
     } 
    } 
    ] 
} 

現在,我把下面的代碼在我的模型:

class Taxonomy < ActiveRecord::Base 

    has_many       :terms, 
             -> {order(:id)} 


    def update_terms(params) 

    existing_term_ids = terms.map &:id 

    create_term = lambda do |term_params, parent=nil| 
     t = terms.find_by(:id => term_params[:id]) if term_params[:id] 
     t ||= terms.build 
     t.attributes = term_params.slice(:slug, :data, :overridable_data, :term_data) 
     t.parent = parent 
     t.save 
     existing_term_ids.delete(t.id) 

     if term_params.has_key?(:children) 
     term_params[:children].each do |child_params| 
      create_term.call(child_params, t) 
     end 
     end 

    end 

    params.each do |term_params| 
     create_term.call(term_params) 
    end 

    terms.where(:id => existing_term_ids).destroy_all 
    save 
    end 
end 

這個版本(快速寫入測試軌道4)採用分片,因爲attr_accessible走了過濾參數。

這讓我想知道這種代碼應該在模型還是控制器中。

回答

1

閱讀本acticle:http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

我的意見,你應該做的服務在這種情況下,像這樣:

# app/services/recursive_update.rb 
class RecursiveUpdate 
    def initalize(source) 
    @source = source 
    end 

    def update(params) 
    # your code here 
    end 

    def create_term(term_params, parent=nil) 
    #.... 
    end 

    def permitted_params 
    #.... 
    end 

    def save 
    @source.save 
    end 
end 

控制器:

updater = RecurciveUpdate.new @model 
updater.update params 
update.save 
+0

我思考類似的東西。隨着我的應用程序的增長,我越來越多地使用這些「非Rails課程」。通常的理論是做胖模型,但是很多代碼可以用這種方式模塊化,並從模型中拉出來。 –