保存和验证来自表单输入的临时虚拟属性的问题

Issue with saving and validating temporary virtual attributes which come from form inputs

我有两个模型:

一个项目有很多项,一个项目属于一个项目。

class Project < ActiveRecord::Base

  attr_accessor :main_color, :secondary_color, :tertiary_color
  has_many :items
  accepts_nested_attributes_for :items

  validates :main_color, :presence => true
  validates :secondary_color, :presence => true
  validates :tertiary_color, :presence => true
end



class Item < ActiveRecord::Base
  belongs_to :project

  validates :title, :presence => true,
            :length => {:maximum => 300}

  validates_presence_of :project
end

每个项目都有主色、次色和三次色。

我想将它们存储在我的数据库中 (PostgreSQL) 作为字符串数组(我已经为此设置了迁移),但我必须单独显示它们 在使用颜色输入字段的表单中,并验证它们。

我已经使用虚拟属性来实现,所以颜色不会单独保存,但是我仍然想将它们正确地保存为一个数组,我应该怎么做?

我的项目模型中还发生了另一个与颜色相关的问题。

每个项目都验证项目的存在。我有一个页面,用户可以在其中向项目添加多个项目,并且由于 该项目需要这三种颜色,但它们一团糟,我不断收到验证错误:main_color can't be blanksecondary_color can't be blanktertiary_color can't be blank.

这是我在 ItemsController

中创建项目的方法
 def create

   @project = Project.find(params[:project_id])
   return if !@project

   items = @project.items.build( \
   project_params.to_h['items_attributes'].hash_with_index_to_a)

   @project.items.append(items)

   if @project.save
     redirect_to "/projects/#{@project.id}/items"
   else
     render 'items/new'
   end

 end

这是相关的强参数:

 def project_params
   params.require(:project).permit(:items_attributes =>
                                   [
                                     :id,
                                     :title
                                   ]
                                  )
 end

我应该如何实施它?

嗯,你需要一个属性 setter 和 getter 来实现这个技巧,我希望你将数组保存如下:[main_color, secondary_color, tertiary_color] 并且您在数据库中的列名为 color:

def main_color= m_color
  color ||=[]
  color[0] = m_color
end

def main_color
  color[0]
end

def secondary_color= s_color
  color ||=[]
  color[1] = s_color
end

def secondary_color
  color[1]
end

def tertiary_color= t_color
  color ||=[]
  color[2] = t_color
end

def tertiary_color
  color[2]
end

基于 mohamed-ibrahim's 。这样做怎么样?

class Project < ActiveRecord::Base

  attr_accessor :main_color, :secondary_color, :tertiary_color
  has_many :items
  accepts_nested_attributes_for :items

  validates :main_color, :presence => true
  validates :secondary_color, :presence => true
  validates :tertiary_color, :presence => true

  def main_color=(m_color)
    self.colors ||= []
    self.colors[0] = m_color
  end

  def main_color
    self.colors[0]
  end

  def secondary_color=(s_color)
    self.colors ||= []
    self.colors[1] = s_color
  end

  def secondary_color
    self.colors[1]
  end

  def tertiary_color=(t_color)
    self.colors ||= []
    self.colors[2] = t_color
  end

  def tertiary_color
    self.colors[2]
  end
end