Ruby-on-rails Rails - 添加不在模型中的属性并更新模型属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9376744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails - Add attributes not in model and update model attribute
提问by alex.bour
I have 3 fields in my form witch are not in my database: opening_type, opening_hours, opening_minutes. I want to update the main attribute "opening" (in database) with these 3 fields.
我的表单中有 3 个字段不在我的数据库中:opening_type、opening_hours、opening_minutes。我想用这 3 个字段更新主要属性“opening”(在数据库中)。
I tried lot of things that doesn't work.
我尝试了很多不起作用的东西。
Actually I have:
其实我有:
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
I tried adding something like:
我尝试添加如下内容:
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
But, the accessors methods are not called and I think opening_type, opening_hours, opening_minutes were empty too if the accessors were called...
但是,访问器方法没有被调用,我认为如果访问器被调用,opening_type、opening_hours、opening_minutes 也是空的......
I think I don't need a before_save callback and should do this rewriting the accessors.
我想我不需要 before_save 回调,应该重写访问器。
Notes: - Rails 3.0.5, - opening_type, :opening_hours, :opening_minutes could be empty
注意: - Rails 3.0.5,-opening_type,:opening_hours,:opening_minutes 可以为空
EDIT: I updated my code
编辑:我更新了我的代码
回答by Gareth
Note that attr_reader, attr_writerand attr_accessorare just macros for defining your own methods.
请注意attr_reader,attr_writer和attr_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)
At the moment, your setter methods aren't doing anything special, so if you just switch to attr_accessoryour code will become cleaner.
目前,你的 setter 方法没有做任何特别的事情,所以如果你只是切换到attr_accessor你的代码会变得更干净。
Your other issue is that your opening=method is never being called, and this makes sense because there's nowhere in your code calling it. What you really want is for your opening to be set after all of the individual parts have been set. Now there's no trivial way to do this, but Rails does have a before_validationcallback where you can put code that runs after values have been set but before the validation runs:
您的另一个问题是您的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
回答by davidb
instead of
代替
attr_reader :opening_type, :opening_hours, :opening_minutes
you need
你需要
attr_accessor :opening_type, :opening_hours, :opening_minutes
attr_reader :opening_type, :opening_hours, :opening_minutes
hf...
高频...
// Are :opening_type, :opening_hours, :opening_minutes real fields? If yes then you just need this?
// :opening_type, :opening_hours, :opening_minutes 是真实字段吗?如果是,那么你只需要这个?
attr_accessor :opening attr_reader :opening
attr_accessor :打开 attr_reader :打开

