2015-06-23 24 views
0

我有一個將記錄插入我的數據庫(MySQL)的函數。它有許多列,其中許多列在數據庫中都有默認值。因此傳遞這些變量的值是可選的。如果未傳遞變量,請使用數據庫默認值(Ruby on Rails)

def assign_X_to_Y(options = {}) 
. . . 
@bar.var1 = options[:foo] 
. . . 
end 

我想做到以下幾點:

- 如果一個變量存在(例如:選擇[:FOO]),將其添加到我正在做記錄。

@bar.var1 = options[:foo] 

- 如果沒有,我不想添加它 - 我想使用數據庫默認值。

我知道我可以簡單地做一個if

if options[:foo] 
    @bar.var1 = options[:foo] 
end 

但是我有很多這些變量的,所以我覺得必須有一個更好的方式,如果語句具有負載。類似於「如果不存在設置爲空」的表達式:

@bar.var1 = options[:foo] || nil 

有沒有什麼和我說的一樣?我不能使用上述表達式,因爲我不想將它設置爲空(我認爲它會這樣做),我想使用默認值...

在此先感謝!

+1

您是將值賦給模型還是創建SQL語句?請將'assign_X_to_Y'方法添加到您的問題中。對於甚至沒有與讀者分享的方法,也不可能給出重構建議。 – max

+0

向方法添加了'@bar.var1 = options [:foo]'......這是否澄清了我正在爲模型添加值? –

+1

是的,如果它的模型只是做'@ bar.assign_attributes(options)' – max

回答

1

如果@bar是,你可以簡單地傳遞一個哈希的模型:

Bar.create(hash) # creates a Bar with the defaults from your schema 
@bar.assign_attributes(hash) 
@bar.update(hash) # same as object but commits the changes to the db 

如果酒吧是您可以通過給它相同的功能普通老式Ruby類:

class Bar 

    attr_accessor :foo 
    attr_accessor :baz 
    attr_accessor :woggle 

    def initialize(hash) 
    assign_values(hash) 
    end 

    def assign_attributes(hash) 
    assign_values(hash) 
    end 

    private 

    def assign_values(hash) 
    hash.each do |k,v| 
     send "#{k}=", v 
    end 
    end 
end 

那麼我就可以只需創建一個對象:

Bar.new(foo: 1, baz: 3) 

請注意,這將尊重對象封裝如果我嘗試做:

Bar.new(haxxored: true) 

它會引起NoMethodError。就像@bar.haxxored = true

0

如果我正確理解你的問題,來處理這個最好的辦法是使用Ruby中public_send方法:

def set_new_property(obj, prop_name, prop_value) 
    obj.class.__send__(attr_accessor: "#{prop_name}") 
    obj.public_send("#{prop_name}=", prop_value) 
end 

記住,你必須設定明確的屬性訪問器每個潛在的財產被分配。

+0

或者你可以只做[instance_variable_set](http://apidock.com/ruby/Object/instance_variable_set),如果你要反對封裝。 – max

相關問題