2012-02-21 89 views
7

我在我的形式女巫3场都没有在我的数据库:opening_type,OPENING_HOURS,opening_minutes。我想用这3个字段更新主要属性“开放”(在数据库中)。导轨 - 添加属性不是在模型和更新模型属性

我试过很多东西不起作用。

其实我有:

attr_accessor :opening_type, :opening_hours, :opening_minutes 

    def opening_type=(opening_type) 
    end 
    def opening_type 
    opening_type = opening.split("-")[0] if !opening.blank? 
    end 

    def opening_hours=(opening_hours) 
    end 
    def opening_hours 
    opening_hours = opening.split("-")[1] if !opening.blank? 
    end 

    def opening_minutes=(opening_minutes) 
    end 
    def opening_minutes 
    opening_minutes = opening.split("-")[2] if !opening.blank?  
    end 

我尝试添加类似:

def opening=(opening) 
    logger.info "WRITE" 

    if !opening_type.blank? and !opening_hours.blank? and opening_minutes.blank? 
     opening = "" 
     opening << opening_type if !opening_type.blank? 
     opening << "-" 
     opening << opening_hours if !opening_hours.blank? 
     opening << "-" 
     opening << opening_minutes if !opening_minutes.blank? 
    end 
    write_attribute(:opening, opening) 
    end 

    def opening 
    read_attribute(:opening) 
    end 

但是,在存取方法不叫,我想opening_type,OPENING_HOURS,opening_minutes是空的太多,如果存取器被称为...

我想我并不需要一个before_save回调应该这样做重写访问器。

注: - 的Rails 3.0.5, - opening_type,:OPENING_HOURS,:opening_minutes可能是空的

编辑:我更新了我的代码

回答

15

注意attr_readerattr_writerattr_accessor只是宏定义自己的方法。

# attr_reader(:foo) is the same as: 
def foo 
    @foo 
end 

# attr_writer(:foo) is the same as: 
def foo=(new_value) 
    @foo = new_value 
end 

# attr_accessor(:foo) is the same as: 
attr_reader(:foo) 
attr_writer(:foo) 

此刻,你的setter方法都没有做什么特别的东西,所以如果你只是切换到attr_accessor你的代码将变得更清洁。

你的另一个问题是,你的opening=方法永远不会被调用,这是有道理的,因为在你的代码中调用它没有什么地方。你真正想要的是在你设置好所有的单个零件之后,设置你的开口。现在有做这个非同小可的方式,但Rails的确实有一个before_validation回调,你可以把一个运行值被设置之后,但在验证运行之前代码:

class Shop < ActiveRecord::Base 

    attr_accessor :opening_type, :opening_hours, :opening_minutes 

    before_validation :set_opening 

    private 
    def set_opening 
    return unless opening_type && opening_hours && opening_minutes 
    self.opening = opening_type + "-" + opening_hours + "-" + opening_minutes 
    end 
end 
+0

注意这个答案假设你只想在数据库中存储结合的'opening'字段。另一种方法是将各个组件存储在数据库中,并根据需要动态构建组合字符串。根据您的要求,这可能甚至是更好的方法。 – Gareth 2012-02-21 13:19:14

+0

我得到这个数据库的开场字段。该数据库与智能手机应用程序同步,我无法更改其结构以存储3个不同的字段。 ;-) before_validation回调的问题在于,当我们要编辑表单时...以及我需要在3个变量中截断开始字段...的形式时,您不处理这种情况。我知道我可以手动做到这一点,但我认为有更好的方法来做到这一点... – 2012-02-21 13:34:51

+0

所有的事情都是如此,但是你提出的重写'opening ='的建议会破坏很多东西。另外,使用setter方法非常简单,它可以完全放弃传入的参数。最好有一个单独的方法(比如我的'set_opening'),它明确了它正在做什么。你不*有*使用before_validation来调用该方法,但我严重建议它是一个单独的方法 – Gareth 2012-02-21 13:43:02

0

代替

attr_reader :opening_type, :opening_hours, :opening_minutes 

你需要

attr_accessor :opening_type, :opening_hours, :opening_minutes 
attr_reader :opening_type, :opening_hours, :opening_minutes 

hf ...

//主要有:opening_type,:OPENING_HOURS,:opening_minutes真正的领域?如果是的话,你只需要这个?

attr_accessor:开放 attr_reader:开放

+0

好吧,我改变了attr_accessor。但开放存取不叫... – 2012-02-21 12:50:47

+0

看到更新,.... – davidb 2012-02-21 12:57:14

+0

号真正的领域是我的数据库“开放”。我需要从我的表单发送3个字段:opening_type,opening_hours,opening_minuts填充主“开放”字段。这3个字段不在数据库中。我更新了第一篇文章。 – 2012-02-21 13:04:20