【问题标题】:Add entry to table consisting only of parent model id向仅包含父模型 ID 的表添加条目
【发布时间】:2015-07-07 14:53:40
【问题描述】:

我在一个应用中有两个模型:PersonDirectorperson has_one director。一个人可以是很多东西(官员、承包商等和董事);如果他们是主管,我只想将他们的用户 ID 存储在主管表中,仅此而已。

因此,我设置的表格仅包含 4 列:

mysql> show columns in directors;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| person_id  | int(11)  | YES  | MUL | NULL    |                |
| created_at | datetime | YES  |     | NULL    |                |
| updated_at | datetime | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+
4 rows in set (0.03 sec)

我希望表单上的每个人条目都有一个嵌套的单选按钮,如果它设置为“是”,它会在 Director 表中创建一个条目,如果它设置为“否”,则删除/不创建一个条目。看起来很简单,但我意识到我不知道该怎么做,因为单选按钮的显式值不会保存到数据库中。

有什么好的方法可以解决这个问题吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 activerecord associations nested-forms


    【解决方案1】:

    您可以将attr_accessor 添加到您的Person 模型中,例如is_director。这是一个临时属性,不会存储在数据库中。然后根据is_director的值,可以有一个回调来设置逻辑,让用户成为自己的导演。

    class Person < ...
      ...
    
      attr_accessor :is_director
      after_create  :make_director
    
    private
    
      def make_director
        if self.is_director
          #your logic to make the user their own director
        else
          #some other logic
        end
      end
    end
    

    然后在您的表单中,您可以添加单选按钮:

    <%= f.label :is_director %><br />
    <%= f.label :is_director, "Yes", :value => "true"  %>
    <%= f.radio_button :is_director, true, :checked => is_director?(@person)  %>
    <%= f.label :is_director, "No", :value => "false" %>
    <%= f.radio_button :is_director, false, :checked => !is_director?(@person) %>
    

    然后你可以在persons_helper.rb创建一个助手:

    def is_director?(person)
      #whatever the logic is to check if a person is a director
    end
    

    您还需要将is_director 添加到控制器中强参数的permit 数组中。

    【讨论】:

    • 抱歉,我好像很快就联系上了;以为我有它的工作。我收到一个错误:undefined method id,它与视图中的单选按钮有关。
    • 更新了答案。不知道你的逻辑是什么来检查一个人是否是导演,但你可以把它放在辅助方法中。
    • 感谢您的更新。我目前正在解决关于set_person_id 的错误undefined method parent_id`。如果这个错误有任何明显的原因,我会全力以赴。
    • 答案背后的想法是展示attr_accessor 和回调的使用。我不熟悉您的代码来完全回答这个问题。目前尚不清楚为什么需要一个单独的 director 表(对于现在构建表的方式)。为什么不能只在persons 表上设置一个布尔字段来指示用户是否是主管?如果您希望directors 表同时保存person_id 和它们的manager_id,那么您缺少manager_id 外键
    【解决方案2】:

    如果不存在不同角色需要的任何其他属性,则创建一个包含主管、高级职员、承包商等记录的角色表可能更有意义,而不是使它们成为单独的表。这也使您可以灵活地通过管理面板轻松添加其他角色,而不是通过新表和迁移。

    然后您可以拥有一个连接表,以允许用户通过单选按钮或复选框来属于其中一个或多个角色。

    用户 - has_and_belongs_to_many :roles
    角色 - has_and_belongs_to_many :users

    <legend>Roles</legend>
    <div class="form-group">
      <%= f.collection_check_boxes(:role_ids, Role.all, :id, :name, :item_wrapper_class => 'inline') %>
    </div>
    

    确保在控制器的 user_params 中允许 :role_ids => []

    【讨论】:

      猜你喜欢
      • 2015-03-22
      • 2021-03-16
      • 1970-01-01
      • 2015-06-01
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多