【问题标题】:Why won't my DataMapper record save when I pass it the user it belongs to?为什么当我将它所属的用户传递给我的 DataMapper 记录时,它不会保存?
【发布时间】:2016-09-03 07:45:08
【问题描述】:

我已经使用 DataMapper 和 Sinatra 建立了一个简单的 has-many 和 belongs-to 关联。我的用户模型有很多“窥视”,我的窥视模型属于用户。请参阅下面的课程......

通过在初始化时将 user_id 直接传递给窥视,我能够成功创建属于特定用户的新窥视,如下所示:

方法一

new_peep = Peep.create(content: params[:content], user_id: current_user.id)

这会将 Peep 添加到 Peep.count。

但是,我的理解是我应该能够通过将 current_user 分配给 new_peep.user 来创建关联。但是当我尝试这样做时,窥视对象不会保存。

我试过了:

方法二

new_peep = Peep.create(content: params[:content], user: current_user)

这里的当前用户是 User.get(session[:current_user_id])

生成的 new_peep 的 id 为 nil,但 确实 将 user_id 设置为 current_user 的 id。 New_peep 看起来与使用方法 1 成功创建的 new_peep 完全相同,只是它没有 id,因为它没有成功保存。我试过单独调用 new_peep.save,但我仍然得到下面的窥视对象:

<Peep @id=nil @content="This is a test peep" @created_at=#<DateTime: 2016-05-08T12:42:52+01:00 ((2457517j,42172s,0n),+3600s,2299161j)> @user_id=1>, @errors={}

请注意,没有验证错误。其他人在保存记录方面似乎遇到的大多数问题都归结为不符合验证标准。

我认为这与 belongs_to 关联不起作用有关,但我可以(在使用上面的方法 1 创建 new_peep 之后)仍然调用 new_peep.user 并访问正确的用户。所以在我看来,belongs_to 是作为读者而不是二传手。

这个问题也意味着我无法通过将一个添加到 user.peeps 集合然后保存用户来创建窥视,这意味着窥视属于用户几乎没有意义。

我看到其他人在保存没有任何更改的记录时遇到问题 - 但这是一条全新的记录,因此它的所有属性都在更新。

我真的很想知道发生了什么——这让我困惑了太久!

这是我的课程:

class Peep

    include DataMapper::Resource

    property :id, Serial
    property :content, Text
    property :created_at, DateTime

    belongs_to :user, required: false

    def created_at_formatted
        created_at.strftime("%H:%M, %A %-d %b %Y")
    end

end


class User

    include DataMapper::Resource
    include BCrypt

    attr_accessor :password_confirmation
    attr_reader :password

    property :id, Serial
    property :email, String, unique: true, required: true
    property :username, String, unique: true, required: true
    property :name, String
    property :password_hash, Text

    def self.authenticate(params)
        user = first(email: params[:email])
        if user && Password.new(user.password_hash) == params[:password]
            user
        else
            false
        end
    end

    def password=(actual_password)
        @password = actual_password
        self.password_hash = Password.create(actual_password)
    end

    validates_confirmation_of :password
    validates_presence_of :password

    has n, :peeps

end

【问题讨论】:

  • 您尝试调用有效吗?阅读前记录错误?在 Rails 中,这是加载错误数组所必需的
  • 谢谢马克斯。刚试过。有效的?记录返回 true,errors 集合仍然为空。
  • 你能链接到一个仓库或发布一个完整的脚本来测试它吗?我认为您关于“窥视用户几乎没有意义”的断言是不正确的。我没有看到user: current_user 语法比user_id: current_user.id 的糖更多。 belongs_to :user 关联基本上是def user; User.find_by(id: self.user_id); end 的糖。 belongs_to 方法基本上是为了协助编写更少的代码。

标签: ruby sinatra datamapper


【解决方案1】:

当您创建 Peep 时,您不会通过用户创建它,也许这就是它没有主 ID 的原因,因为它属于用户。此外,您还为其分配了外键 user_id,就好像您有一个这样定义的属性。尽管数据库有它,但在 DataMapper 中,您无需传入外键 id,它会为您完成。

尝试替换

new_peep = Peep.create(content: params[:content], user: current_user)

与:

new_peep = current_user.peeps.create(content: params[:content], created_at: Time.now)

【讨论】:

    猜你喜欢
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2019-10-25
    相关资源
    最近更新 更多