This is a newbie question, but I'm still learning how to create an association between two models in rails. I have a user model and a journal_entry model. The journal entries belong to the user and the user has_many journal entries. I've created migrations that look like this:
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
Here's what my User model looks like:
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
And here's what my journal_entry model looks like:
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
But when I go to create a new journal entry at /journal_entries/new
I just a validation error that says "User can't be blank". So the user_id is not getting added to the journal entry even though I'm logged in and there is a user_id column in my db/schema.rb:
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
Also, this is the form that I'm using on journal_entries/new to create the journal entry:
<%= 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 %>
What am I missing here? Do I need to add the user_id as a hidden field on the form?
i bet, that u forget something like
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_entry model should look like
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
This should work!
You need to add user_id to your attr_accessible
call, if you look at your logs it is probably warning you that it can't mass assign it.
Ok, so I got this working by adding the user to the create action in my journal_entries_controller.rb. Here's the code I used, but is this the "rails way" to do this?
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
you have it right this time. You added the user association to the journal model which loads the user in the controller before displaying it in the view. You do need the hidden fields in your form which you added, since you are using a stateless protocol. On the update/create action, double check that the user posting is the user using and save.
来源:https://stackoverflow.com/questions/11354724/how-to-create-an-association-between-two-rails-models