Rails形式:如果已经有这个孩子,则不要以形式显示孩子

时间:2018-11-19 19:25:10

标签: ruby-on-rails

Person.rb:

class Person < ApplicationRecord
  has_many :skills
end

Skill.rb:

   class Skill < ApplicationRecord
      belongs_to :person
      validates_uniqueness_of :name, :scope => :person_id
    end

我制作了嵌套在Routes.rb中的技能:

  resources :people do 
    resources :skills
    end
  end

现在,当在clients/1/skills/new中为客户创建新技能时,我不想选择客户已经拥有的技能。怎么做到呢?这是我当前的输入字段:

= f.select :skill_id, Skill.all.map{|c| [c.name, c.id]}, {include_blank: true}

2 个答案:

答案 0 :(得分:0)

我不知道您正在运行哪个Rails版本,但是您可以为Skill类创建范围。

 scope :remaining, ->(name) { where.not(name: name) }

然后更新您的视图:

 = f.select :skill_id, Skill.remaining(@person.skills.map(&:name)).map { |c| [c.name, c.id] }, { include_blank: true }

未经测试,不确定是否需要.map :name,但您知道了。如果更适合您的用例,也可以将:name更改为:id(我不确定您是全面还是仅针对每个用户实施技能唯一性)。

但是,对于您的视图而言,它看起来有些笨拙,因此,如果您具有正确的列,则可以将其放入Skill类中。

def self.remaining # you're mapping the skill, not the client
  where.not(id: person.skill_ids).map { |s| [s.name, s.id] }
end

然后视图将是:

= f.select :skill_id, Skill.remaining, { include_blank: true }

顺便说一句,我猜想/clients/people是同一件事,只是在SO上有不同的名称,否则会引起头痛和/或折断。

答案 1 :(得分:0)

in person.rb

def available_skills 
   skills = self.skills.pluck(:name, :id)
   Skill.pluck(:name, :id).select{|s| !skills.include?(s)}
end 

在视图模板中:

<%= f.select :skill_id, @person.available_skills, {include_blank: true} %>