【问题标题】:Rails 3 has_one / belongs_to relationship with model in subdirectoryRails 3 has_one / belongs_to 与子目录中模型的关系
【发布时间】:2012-08-22 20:47:57
【问题描述】:

我正在尝试创建一个简单的关系,但模型位于 Rails 3.2 下的子目录中

我有一个 User 类,每个用户都有一个电子邮件订阅。因为会有其他类型的订阅(也填充添加到用户)我把它们放在一个子目录中。 (我的用户恰好来自 Devise,但我怀疑这无关紧要。)

这是代码

model/user.rb

class User < ActiveRecord::Base
  has_one :email_sub

  before_create :build_email_subscription

  private

  def build_email_subscription
    Subscription::EmailSub.create(:is_subscribed => true, :user_id => self.id)
    true
  end
end

请注意,我还创建了一种添加默认订阅的方法。

model/subscriptions/email_sub.rb

class Subscriptions::EmailSub < ActiveRecord::Base
  belongs_to :user
end

除了创建两个类的迁移之外,我还为关系创建了以下迁移。

class AddSubscriptionToUser < ActiveRecord::Migration
  def change_table :subscriptions_email_sub do |t|
    t.referneces :users
  end
end

但是,这似乎不起作用。它似乎没有生成user_id 列。

【问题讨论】:

  • 注意:引用拼写错误。我也会尝试使用 add_column subscriptions_email_sub user_id:integer

标签: ruby-on-rails-3 migration belongs-to subdirectory has-one


【解决方案1】:

看起来我让它工作了。我正在分享和注释我的结果以供其他人学习。

model/user.rb

class User < ActiveRecord::Base
  has_one :email_sub, :class_name => "Subscriptions::EmailSub"

  before_create :build_email_subscription

  private

  def build_email_subscription
    build_email_sub(:announcements => true, :notifications => true, :master => true)
    true
  end
end

我明确包含class_name 以在子目录中查找模型。我使用了build_&lt;attribute&gt; 并传入了三个订阅的参数(后来从一个表单中传入,但现在只是设置默认值)。

model/subscriptions/email_sub.rb

class Subscriptions::EmailSub < ActiveRecord::Base
  attr_accessible :announcements, :daily_deals, :master
  belongs_to :user
end

(我在上面省略了属性,因为它们与问题并不真正相关,但我会明确地将它们包含在此处以供初学者使用。)

我修改了 EmailSubs 模型的原始迁移,而不是新的迁移。

class CreateSubscriptionsEmailSubs < ActiveRecord::Migration
  def change
    create_table :subscriptions_email_subs do |t|
      t.boolean :master
      t.boolean :daily_deals
      t.boolean :announcements

      t.references :user    # I added this line to the generated migration
      t.timestamps
    end
  end
end

我添加了t.references 行。请注意,我之前使用的是复数而不是单数(在迁移中,表名必须是复数,字段单数)。 t.references 会知道寻找给定的 _id 字段。

希望这可以帮助其他人节省一些时间。

【讨论】:

    【解决方案2】:

    我会重做您设置模型的方式。我认为尝试编辑 rails 自动创建的关系表并不是一个好习惯。

    对于您的模型 user.rb

    class User < ActiveRecord::Base
        has_many :subscriptions
        // Put whatever before_create logic here if that's still working correctly
    end
    

    将 subscription.rb 更改为:

    class Subscription < ActiveRecord::Base
        belongs_to :user
        belongs_to :subscription_type
    end
    

    然后制作另一个模型,subscription_type.rb

    class SubscriptionType < ActiveRecord::Base
        has_many :subscriptions
    end
    

    此模型将有 3 列:id、subscription_id 和 subscription_type_id,(可能还有一个列 subscription_type_name)。然后进行约定,例如,subscription_type_id 1 是电子邮件订阅,2 是杂志订阅等等。或者,您可以在订阅模型中添加一个 subscription_type 列。

    为了更轻松地查看模型中的列,请使用annotate gem,这是how to use 的快速教程

    【讨论】:

    • 谢谢,但这并不能完全解决问题。首先是我将订阅保存在子目录中,并且我不能 100% 确定我引用了该类的权利。因为我将有多个订阅,所以我想使用一个子目录。第二个是订阅类型不起作用。例如,电子邮件订阅实际上支持用户可能收到的 3 种不同类型的电子邮件。 EmailSub 类中有 3 个不同的布尔值。其他订阅模型将类似,因此我想在子目录中为每个订阅模型保留一个不同的类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多