回滚事务rails console

时间:2016-12-11 21:24:01

标签: ruby-on-rails database rails-console

当我尝试基于用户创建新事件时,我遇到了rails控制台的问题。我觉得这是一个非常简单的错误,但我发帖是因为我不确定应该如何修复它。这是我试图运行的命令:

user.event = Event.create(:name => "Dummy")

这是我的事件的db文件:

class CreateEvents < ActiveRecord::Migration[5.0]
  def change
    create_table :events do |t|
      t.string :name

      t.timestamps
    end
  end
end

这是我的用户数据库文件:

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      t.string :event
      t.integer :code


      t.timestamps
    end
  end
end

这是我的User.rb文件:

class User < ApplicationRecord
    has_secure_password
    has_many :events

    def User.digest(string)
        cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
        BCrypt::Password.create(string, cost: cost)
    end
end

这是我的Event.rb文件:

class Event < ApplicationRecord
    belongs_to :user
end

2 个答案:

答案 0 :(得分:1)

表格中没有外键。假设您实际上打算按照说明使用模型(&#34;事件属于用户&#34; /&#34;用户有很多事件&#34;),您需要在列表中添加user_id列。事件表,而不是用户表的event字符串。

您可以使用references类型使用迁移/模型生成器创建迁移或列定义:

rails g model event name:string user:references

rails g migration add_user_id_to_event user:references

将添加列和所需的索引。

此外,你有一个用户许多事件,所以没有什么比这更像

user.event = Event.create

(没有User#event=这样的方法),而是

user.events << Event.create(...)

答案 1 :(得分:1)

这不是一个简单的错误。这是一些错误的事情。

如果您想要一个用户可以拥有多个事件的关系,并且一个事件可以属于许多用户,则需要创建一个连接表。在用户或事件表上存储外键会产生一对多关系,这可能不是你想要的。

class User < ApplicationRecord
  has_many :user_events
  has_many :events, through: :user_events
end

class Event < ApplicationRecord
  has_many :user_events
  has_many :users, through: :user_events
end

# this is a join model.
class UserEvent < ApplicationRecord
  belongs_to :user
  belongs_to :event
end
  

has_many :through association通常用于设置多对多   与另一个模型的连接。这种关联表明了   声明模型可以与另一个的零个或多个实例匹配   通过第三个模型进行模型化。   http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

您可以通过运行:

生成UserEvent模型和创建连接表的迁移
rails g model user_event user:belongs_to event:belongs_to

这将创建一个user_events表,其中包含user_idevent_id个外键列。您还应该回滚创建users表并进行修复的迁移:

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      t.string :password_digest # !!!
      t.integer :code
      t.timestamps
    end
  end
end

请注意添加password_digest列 - 这是has_secure_password所必需的。如果您已在生产数据库上运行此迁移或已提交并推送它,则应创建单独的迁移来修复错误:

class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column(:users, :password_digest, :string)
  end
end

class RemoveEventFromUsers < ActiveRecord::Migration[5.0]
  def change
    remove_column(:users, :event)
  end
end

要创建与用户关联的事件,您可以执行以下操作:

event = user.events.new(name: "Dummy") # does not persist the record
event = user.events.create(name: "Dummy") 

您可以使用铲运算符从任一端分配记录:

user.events << event
event.users << user

这对我来说是正确的关联吗?

  

我的应用程序的主要目标是让用户拥有partys和   那些派对有歌。

只有一个用户的派对听起来很蹩脚。但是,如果要为用户创建特殊关系,可以创建单独的关联:

class User < ApplicationRecord
  has_many :user_events
  has_many :events, through: :user_events
  has_many :owned_events, class_name: 'Event', foreign_key: 'owner_id' 
end

class Event < ApplicationRecord
  has_many :user_events
  has_many :users, through: :user_events
  belongs_to :owner, class_name: 'User'
end

class AddOwnerIdToEvents < ActiveRecord::Migration[5.0]
  def change
    add_column(:events, :owner_id, :integer)
    add_foreign_key(:events, :users, column: :owner_id)
  end
end

解决此问题的另一种方法是向UserEvent连接模型添加一列,以指定关联的内容。但这远远超出了你的技能水平。