【问题标题】:How to create an association between two rails models如何在两个 Rails 模型之间创建关联
【发布时间】:2012-07-06 01:26:52
【问题描述】:

这是一个新手问题,但我仍在学习如何在 Rails 中的两个模型之间创建关联。我有一个用户模型和一个 journal_entry 模型。日记条目属于用户并且用户有_many 日记条目。我创建了如下所示的迁移:

class AddJournalEntriesToUsers < ActiveRecord::Migration
  def change    
    add_column :journal_entries, :user_id, :integer
  end
end

class AddIndexToJournalEntries < ActiveRecord::Migration
  def change
    add_index :journal_entries, [:user_id, :created_at]
  end
end

这是我的用户模型的样子:

class User < ActiveRecord::Base
  authenticates_with_sorcery!

  attr_accessible :email, :password, :password_confirmation

  has_many :journal_entries, dependent: :destroy

  validates_confirmation_of :password, :message => "should match confirmation", :if => :password
  validates_length_of :password, :minimum => 3, :message => "password must be at least 3 characters long", :if => :password
  validates_presence_of :password, :on => :create
  validates_presence_of :email
  validates_uniqueness_of :email

end

这就是我的 journal_entry 模型的样子:

class JournalEntry < ActiveRecord::Base
  attr_accessible :post, :title, :user_id

  belongs_to :user

  validates :user_id, presence: true

  default_scope order: 'journal_entries.created_at DESC'
end

但是当我在/journal_entries/new 创建一个新的日记帐分录时,我只是一个验证错误,上面写着“用户不能为空”。因此,即使我已登录并且我的 db/schema.rb 中有一个 user_id 列,user_id 也不会添加到日志条目中:

create_table "journal_entries", :force => true do |t|
    t.string   "title"
    t.text     "post"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
    t.integer  "user_id"
  end

另外,这是我在 journal_entries/new 上用来创建日记条目的表单:

<%= form_for(@journal_entry) do |f| %>
  <% if @journal_entry.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@journal_entry.errors.count, "error") %> prohibited this journal_entry from being saved:</h2>

      <ul>
      <% @journal_entry.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :post %><br />
    <%= f.text_area :post %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

我在这里缺少什么?我需要将 user_id 添加为表单上的隐藏字段吗?

【问题讨论】:

  • 你能把代码贴在你的 JournalEntriesController#create 中吗?
  • 你在哪里设置用户到期刊?请发布该代码
  • 我编辑了问题,在 journal_entries/new 上包含创建日记条目的表单。
  • 是的,您需要表单中的 user_id!
  • 好的,如果我将 user_id 添加到这样的形式,它可以正常工作` current_user.id %>` 但我认为关联是应该的为您处理。 rails 不应该通过关联分配 user_id,还是您总是需要将 user_id 作为隐藏字段包含在表单中?

标签: ruby-on-rails ruby rails-models


【解决方案1】:

我敢打赌,你会忘记类似的事情

def create
    @journal_entry = @user.journal_entries.build(params[:journal_entry])
    # @journal_entry = current_user.journal_entries.build(params[:journal_entry])
    if @journal_entry.save
    ..

【讨论】:

  • 好的,这确实是答案。我需要将用户添加到 journal_entries_controller def create @user = current_user @journal_entry = @user.journal_entries.build(params[:journal_entry]) if @journal_entry.save flash[:success] = "Journal entry created!" end 中的创建操作
【解决方案2】:

journal_entry 模型应该是这样的

class JournalEntry < ActiveRecord::Base
  attr_accessible :post, :title, :user_id
  belongs_to :user
  validates :user_id, presence: true
  default_scope order: 'journal_entries.created_at DESC'
end

这应该可行!

【讨论】:

  • 我在attr_accessible 中添加了:user_id,但它仍然说user_id 不能为空
  • 我必须像 &lt;%= f.hidden_field :user_id, :value =&gt; current_user.id %&gt; 这样在我的表单上添加 user_id 作为隐藏字段才能使其正常工作。这是 Rails 约定吗?
  • 另外,请注意,我认为将:user_id 列为attr_accessible 是出于安全考虑。您不希望 user_id 被批量分配,对吗? stephensclafani.com/2010/01/04/…
【解决方案3】:

您需要将 user_id 添加到您的 attr_accessible 调用中,如果您查看日志,可能会警告您无法批量分配它。

【讨论】:

  • 我编辑了问题以包含新的 journal_entry 模型。将user_id 添加到attr_accessible 不起作用。
【解决方案4】:

好的,所以我通过将用户添加到我的 journal_entries_controller.rb 中的创建操作来完成这项工作。这是我使用的代码,但这是执行此操作的“rails 方式”吗?

def create
  @user = current_user
  @journal_entry = @user.journal_entries.build(params[:journal_entry])
  if @journal_entry.save
    flash[:success] = "Journal entry created!" 
  end
end

【讨论】:

  • 99% rails way :-),缺少 1% 因为@user 变量没用,足以使用 current_user。祝你好运!
【解决方案5】:

这次你做对了。您将用户关联添加到日志模型中,该模型在将用户显示在视图中之前将其加载到控制器中。 您确实需要您添加的表单中的隐藏字段,因为您使用的是无状态协议。 在更新/创建操作中,仔细检查用户发布的用户是否正在使用并保存。

【讨论】:

  • 我从表单中删除了隐藏字段,它工作正常。它使用正确的 user_id 发布
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
  • 2010-11-21
相关资源
最近更新 更多