【问题标题】:How to create automated association in ruby on rails with mysql如何使用 mysql 在 ruby​​ on rails 中创建自动关联
【发布时间】:2014-08-12 09:35:38
【问题描述】:

我有 2 个相互连接的表。

设备和推送信息是我的模型。

class Device < ActiveRecord::Base

    has_one :pushinformation
end


class Pushinformation < ActiveRecord::Base

    belongs_to :device
end

这是我的 2 个模型文件及其关系。

这些是我的迁移文件

class CreateDevices < ActiveRecord::Migration
  def change
    create_table :devices do |t|
      #t.integer :id
      t.string "token" 
      t.string "carrier"
      t.string "segment"
      #t.datetime :created_at
      #t.datetime :updated_at

      t.timestamps
    end
  end
end



class CreatePushinformations < ActiveRecord::Migration
  def change
    create_table :pushinformations do |t|

        t.integer "device_id"

        #t.string "token"
        t.string "first_name"
        t.string "last_name"
        t.string "nickname"

      t.timestamps
    end
  end
end

现在的问题是,我能够通过说在 rails 控制台中成功创建关系

device.pushinformation=push

它们是关联的。

我怎样才能使这个过程自动化,比如当我添加一个设备时——它也会填充一个推送信息表,

我想过拥有相同的属性并将它们关联起来可能是解决方案。在这种情况下,它的令牌和它是完全独一无二的。

我怎样才能建立这种关系?我需要能够知道哪个设备有什么样的 first_name

我是 ruby​​ 的初学者,这是一个新手问题对不起大家 :)

【问题讨论】:

  • 你想要一个表格来填写两个模型还是我误解了?
  • 我想在它们之间建立一个链接,以了解哪个令牌具有哪个名字@knotito
  • 顺便说一句,您需要将CamelCase 用于PushInformation

标签: mysql ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

我不确定我是否完全理解你的问题,但我猜你可以在创建时使用回调

class Pushinformation < ActiveRecord::Base
  belongs_to :device

  after_create :create_push_notification

  private

  def create_push_notification
    ...
  end
end

查看文档

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

【讨论】:

    【解决方案2】:

    xlembouras 的回答是对的(在一定程度上),但由于你是新手,让我为你解释一下:

    --

    协会

    ActiveRecord associations 没有什么神奇之处,它们只是使用关系数据库设置关联两个“对象”的一种方式。

    ActiveRecord 是一个 ORM -- “对象关系映射器” -- 这基本上意味着它只是为 ActiveRecord 对象提供了一个抽象级别,以便相互关联

    这就是问题的症结所在 - 您需要了解如何以及为什么您的关联会起作用,更重要的是,如何正确填充它们:

    --

    模型

    首先,您需要了解 Ruby 的 object-orientated 特性(以及由于运行在 Ruby、Rails 上)。这就是 Rails 的 Models 发挥如此重要作用的地方——它们允许您从数据库中构建和管理 objects

    ActiveRecord 关联使您能够管理这些对象所具有的关联 - 如果您构建一个关联,则应该能够构建另一个:

    #app/models/device.rb
    Class Device < ActiveRecord::Base
       has_one :push_information
       before_create :build_push_information #-> creates associative object before creation
    end
    
    #app/models/push_information.rb
    Class PushInformation < ActiveRecord::Base
       belongs_to :device
    end
    

    您需要考虑我上面所写内容的重要性。

    您需要创建一个push_information 对象,其foreign_keydevice 对象相同,这可以通过使用build 方法来实现

    这实质上将创建关联对象的“空白”版本,并使用正确的外键等保存它

    --

    嵌套

    除此之外,你必须欣赏“嵌套”的想法,尤其是方法accepts_nested_attributes_for

    这允许您基于您的“父”对象创建关联/依赖对象:

    #app/models/device.rb
    Class Device < ActiveRecord::Base
       has_one :push_information
       accepts_nested_attributes_for :push_information
    end
    
    #app/models/push_informtion.rb
    Class PushInformation < ActiveRecord::Base
       belongs_to :device
    end
    

    这使您能够执行以下操作:

    #app/controllers/devices_controller.rb
    Class DevicesController < ApplicationController
       def new
           @device = Device.new
           @device.build_push_information
       end
    
       def create
           @device = Device.new(device_params)
           @device.save
       end
    
       private
    
       def device_params
           params.require(:device).permit(:your, :device, :params, push_information_attributes: [:push, :information, :attributes])
       end
    end
    

    这使您能够像这样填充devices#new 表单:

    #app/views/devices/new.html.erb
    <%= form_for @device do |f| %>
       <%= f.text_field :your_device_attributes %>
       <%= f.fields_for :push_information do |p| %>
           <%= p.text_field :your_field %>
       <% end %>
       <%= f.submit %>
    <% end %>
    

    【讨论】:

      【解决方案3】:

      添加create Devise 类的方法。比如:

      def self.create(token, carrier, segment)
       device = Device.new(:token => token, :carrier => carrier, :segment => segment)
       pi = Pushinformation.create(device.id,..) # other params 
      end
      

      【讨论】:

        猜你喜欢
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-28
        • 2013-04-23
        • 1970-01-01
        • 2016-05-10
        相关资源
        最近更新 更多