问题
I'm relatively new to RoR, and have been working on a lesson-site sharing back-end.
Currently I have two models: Lesson and Revision. The idea is that a teacher would create a lesson (with a title, description, etc.), at the lesson/new page. The form would redirect to another form with other fields (content, comments) at the lesson/lesson_id/revision/new page. Eventually teachers will be able to "save and modify" lessons by copying revisions to their own profile, but the model isn't there yet.
I'm still focusing on two supposedly basic issues, both in creating new lessons and revisions.
1) Saving the lessons to a user, and revisions to a user and lesson. At one point I had revisions saved to users, but lessons were not saving.
2) Redirecting from the lesson form to the revision form, and the revision form to the revision page. I've tried changing the redirects in the controller and one of the form_for blocks, to no avail. The new lesson form still wants to go to /lessons rather than /lesson/1/revision/new, which I've tried to redirect to with new_lesson_revision_path. The revision form also just goes back to /revisions, which will be an admin index but I'd rather go to /lesson/1/revision/1 etc.
Thanks in advance for any advice on either or both of these issues!
Below is my code for reference. An excerpt from routes.rb:
resources :lessons
resources :revisions #For index pages for admin
resources :lessons do
resources :revisions
end
Models
class Lesson < ActiveRecord::Base
attr_accessible :stable, :summary, :title, :time_created
has_many :revisions, :class_name => "Revision"
has_many :users, :through => :revisions
end
class Revision < ActiveRecord::Base
attr_accessible :comment, :lesson_id, :user_id, :description, :content, :time_updated
belongs_to :lesson, :class_name => "Lesson", :foreign_key => "lesson_id"
belongs_to :user, :class_name => "User", :foreign_key => "user_id"
accepts_nested_attributes_for :lesson
end
Lessons new.html.erb
<% if user_signed_in? %>
<h2>New lesson</h2>
<%= form_for @lesson do |f| %>
<%= render "form" %>
<% end %>
<%= link_to 'Back', lessons_path %>
<% else %>
<h3> Please <%= link_to 'sign in', new_user_session_path %> or <%= link_to 'create an account', new_user_registration_path %> to make and save lessons.</h3>
<% end %>
Lessons _form.html.erb
<%= form_for @lesson, :url => new_lesson_revision_path(@lesson_id, @revision) do |f| %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :summary %><br />
<%= f.text_area :summary %>
</div>
<div class="field">
<%= f.label :stable %><br />
<%= f.check_box :stable %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Revisions new.html.erb
<% if user_signed_in? %>
<h2>New revision</h2>
<%= form_for @revision do |f| %>
<%= render "form" %>
<% end %>
<%= link_to 'Back', lessons_path %>
<% else %>
<h3> Please <%= link_to 'sign in', new_user_session_path %> or <%= link_to 'create an account', new_user_registration_path %> to make and save revisions.</h3>
<% end %>
Revisions _form.html.erb
<%= form_for(@revision) do |f| %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="field">
<%= f.label :comment %><br />
<%= f.text_area :comment %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Lesson Controller: new/create
def new
@lesson = Lesson.new
end
def create
@user = current_user
@lesson = Lesson.new(params[:lesson])
#@user.lessons << @lesson
params[:lesson][:user_id] = current_user.id
params[:lesson][:lesson_id] = @lesson.id
respond_to do |format|
if @lesson.save
format.html { redirect_to new_lesson_revision_path(params[:lesson_id]), notice: 'Your lesson was successfully created.' }
format.json { render json: @lesson, status: :created, location: new_lesson_revision_path}
else
format.html { render action: "new" }
format.json { render json: @lesson.errors, status: :unprocessable_entity }
end
end
end
Revisions Controller: new/create
def new
@revision = Revision.new
end
def create
@lesson = Lesson.find(params[:lesson_id])
@revision = @lesson.revisions.new(params[:revision])
@revision.user_id = current_user.id
@revision.lesson_id = @lesson.id
@revision.time_updated = DateTime.now
respond_to do |format|
if @revision.save
format.html { redirect_to current_user.profile }
format.json { }
else
render :new
end
end
end
Lastly here are most of the results from my rake routes:
home_index GET /home/index(.:format) home#index
profile POST /profile(.:format) profiles#create
new_profile GET /profile/new(.:format) profiles#new
edit_profile GET /profile/edit(.:format) profiles#edit
GET /profile(.:format) profiles#show
PUT /profile(.:format) profiles#update
DELETE /profile(.:format) profiles#destroy
lessons GET /lessons(.:format) lessons#index
POST /lessons(.:format) lessons#create
new_lesson GET /lessons/new(.:format) lessons#new
edit_lesson GET /lessons/:id/edit(.:format) lessons#edit
lesson GET /lessons/:id(.:format) lessons#show
PUT /lessons/:id(.:format) lessons#update
DELETE /lessons/:id(.:format) lessons#destroy
lesson_revisions GET /lessons/:lesson_id/revisions(.:format) revisions#index
POST /lessons/:lesson_id/revisions(.:format) revisions#create
new_lesson_revision GET /lessons/:lesson_id/revisions/new(.:format) revisions#new
edit_lesson_revision GET /lessons/:lesson_id/revisions/:id/edit(.:format) revisions#edit
lesson_revision GET /lessons/:lesson_id/revisions/:id(.:format) revisions#show
PUT /lessons/:lesson_id/revisions/:id(.:format) revisions#update
DELETE /lessons/:lesson_id/revisions/:id(.:format) revisions#destroy
GET /lessons(.:format) lessons#index
POST /lessons(.:format) lessons#create
GET /lessons/new(.:format) lessons#new
GET /lessons/:id/edit(.:format) lessons#edit
GET /lessons/:id(.:format) lessons#show
PUT /lessons/:id(.:format) lessons#update
DELETE /lessons/:id(.:format) lessons#destroy
root / home#index
/profile(.:format) profiles#show
回答1:
Your question : 1) Saving the lessons to a user, and revisions to a user and lesson. At one point I had revisions saved to users, but lessons were not saving.
see on your lessons_form
<%= form_for @lesson, :url => new_lesson_revision_path(@lesson_id, @revision) do |f| %>
You are using new_lesson_revision_path
action form, this is not saving a @lesson
, change your lessons_form
to :
<%= form_for @lesson do |f| %>
and lessons_controller.rb
looks like :
def new
@lesson = Lesson.new
end
def create
@user = current_user
@lesson = Lesson.new(params[:lesson])
....
@lesson.save
# see, redirect_to new lesson with params[lesson_id]
redirect_to new_lesson_revision_path(params[:lesson_id])
end
and on revisions_controller.rb
looks like :
def new
@revision = Revision.new
# get @lesson with params(:lesson_id)
@lesson = Lesson.find(params[:lesson_id])
end
def create
@revision = @revision.new(params[:revision])
@revision.user_id = current_user.id
@revision.time_updated = DateTime.now
respond_to do |format|
if @revision.save
format.html { redirect_to current_user.profile }
format.json { }
else
render :new
end
end
end
and on your revisions_form
, you can add lesson_id
with hidden_field
<%= form_for(@revision) do |f| %>
<%= f.hidden_field :lesson_id, :value => @lesson.id %>
..
..
<% end %>
no 2
Why should you not use nested form or multistep form?
If you are use nested form, you can make lessons_form and revisons_form in one form.
see screencasts part 1 and part 2 for nested form
If you are using multistep form, you can resolved you problem
no 2
see screencasts Wizard Forms
Addtional
error: undefined method 'revisions' for nil:NilClass - from the line @revision = @lesson.revisions.new(params[:revision])
Because @revision
is stand-alone on your case, you could change this
@revision = @lesson.revisions.new(params[:revision])
to
@revision = @revision.new(params[:revision])
来源:https://stackoverflow.com/questions/16706372/saving-and-redirecting-with-a-model-and-revision-model-in-rails