Rails - Add attributes not in model and update model attribute

六月ゝ 毕业季﹏ 提交于 2019-12-23 08:58:59

问题


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.

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...

I think I don't need a before_save callback and should do this rewriting the accessors.

Notes: - Rails 3.0.5, - opening_type, :opening_hours, :opening_minutes could be empty

EDIT: I updated my code


回答1:


Note that attr_reader, attr_writer and attr_accessor are just macros for defining your own methods.

# 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_accessor your code will become cleaner.

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_validation callback where you can put code that runs after values have been set but before the validation runs:

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



回答2:


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?

attr_accessor :opening attr_reader :opening



来源:https://stackoverflow.com/questions/9376744/rails-add-attributes-not-in-model-and-update-model-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!