Пожалуйста, просмотрите ОБНОВЛЕНИЯ внизу вопроса...
Для справки эта проблема возникла из некоторых исправлений, которые я сделал на основе предыдущей проблемы, которую я имел здесь: Связывание двух моделей в Rails (пользователь и профиль)
Я создаю приложение с моделью пользователя и моделью профиля.
Я хочу связать эти модели так, что:
- После того, как пользователь создал учетную запись, он автоматически отправляется на страницу "создать профиль", а создаваемый им профиль подключается только к определенному пользователю.
- Только пользователь, которому принадлежит профиль, может его редактировать.
Я создал модель пользователя, используя nifty_generators. Когда пользователь нажимает "Отправить" для создания учетной записи, я перенаправляю его на "новый профиль", чтобы создать профиль. Я сделал это, отредактировав путь перенаправления в пользовательском контроллере. Пользовательский контроллер выглядит следующим образом:
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
session[:user_id] = @user.id
flash[:notice] = "Thank you for signing up! You are now logged in."
redirect_to new_user_profile_path(:user_id => @user)
else
render :action => 'new'
end
end
Когда я нажимаю "submit", чтобы создать нового пользователя, он теперь отправляет меня на следующий URL-адрес, который кажется правильным: localhost: 3000/users/6/profile/new. Но это вызывает следующее исключение:
NoMethodError в ProfilesController # new У вас есть ниль, если вы этого не ожидали! Ошибка при оценке nil.build
Трассировка указывает, что проблема находится в контроллере профилей в методе "Новый". Контроллер профилей выглядит следующим образом:
def index
@user = User.find(params[:user_id])
@profile = @user.profile(:order => "created_at DESC")
end
def show
@user = User.find(params[:user_id])
@profile = @user.profile.find(params[:id])
end
def new
@user = User.find(params[:user_id])
@profile = @user.profile.build
end
def edit
@user = User.find(params[:user_id])
@profile = @user.profile.find(params[:id])
end
def create
@user = User.find(params[:user_id])
@profile = @user.profile.build(params[:profile])
if @profile.save
flash[:notice] = 'Profile was successfully created.'
redirect_to(@profile)
else
flash[:notice] = 'Error. Something went wrong.'
render :action => "new"
end
end
Кроме того, приложение также генерирует исключение, когда я пытаюсь просмотреть страницу индекса профилей (в настоящее время нет профилей, потому что я не могу пройти шаг создания пользователя, чтобы создать его). Это исключение:
ActiveRecord:: RecordNotFound в профиле ProfilesController #
Не удалось найти пользователя без идентификатора
Это то, что говорит мне журнал:
Обработка профилейКонтроллер # index [GET] Параметры: { "Действие" = > "Индекс", "controller" = > "profiles" }
ActiveRecord:: RecordNotFound (не удалось найти пользователя без ID):
приложение/контроллеры/profiles_controller.rb: 5: в `Индекс"
Чтобы предоставить вам остальную информацию о приложении, модели имеют следующие ассоциации:
Профиль принадлежит _to: пользователь
Пользователь _one: профиль
У меня это в файле routes.rb: map.resources: users,: has_one = > : profile
В представлении новой страницы профиля, которая бросает первое исключение, указанное выше, у меня есть следующее:
<% form_for([@user, @profile]) do |f| %>
<%= f.error_messages %>
....
<% end %>
В представлении для индекса профиля, который бросает второе исключение, описанное выше, у меня есть следующее:
<% @profiles.each do |profile| %>
<div class="post">
<div class="left">
<p>Store: </p>
<p>Category: </p>
</div>
<div class="right">
<p><%=h profile.name %></p>
<p><%=h profile.category %></p>
</div>
<div class="bottom">
<p><%= link_to 'Go to profile', user_profile_path(@user, profile) %></p>
<p><%= link_to 'Edit', edit_user_profile_path(@user, profile) %></p>
<p><%= link_to 'Destroy', user_profile_path(@user, profile), :confirm => 'Are you sure?', :method => :delete %></p>
</div>
Я потратил часы, пытаясь отследить проблему самостоятельно как упражнение, но на данный момент я понятия не имею, как это исправить. Цените помощь!
ОБНОВЛЕНИЕ:
jdl, по вашему запросу:
profiles/new.html.erb:
<% form_for([@user, @profile]) do |f| %>
<%= f.error_messages %>
<div class="left">
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>required
</p>
<p>
<%= f.label :category %><br />
<%= f.text_field :category %>required
</p>
<p>
<%= f.label :address1 %><br />
<%= f.text_field :address1 %>
</p>
<p>
<%= f.label :address2 %><br />
<%= f.text_field :address2 %>
</p>
<p>
<%= f.label :city %><br />
<%= f.text_field :city %>
</p>
<p>
<%= f.label :state %><br />
<%= f.text_field :state %>
</p>
<p>
<%= f.label :zip %><br />
<%= f.text_field :zip %>required
</p>
<p>
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
</div>
<div class="right">
<p>
<%= f.label :website %><br />
<%= f.text_field :website %>
</p>
<p>
<%= f.label :description %><br />
<%= f.text_area :description %>
</p>
</div>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
routes.rb:
ActionController:: Routing:: Routes.draw do | map |
map.signup 'signup',: controller = > 'users',: action = > 'new'
map.logout 'logout',: controller = > 'sessions',: action = > 'destroy'
map.login 'login',: controller = > 'sessions',: action = > 'new'
map.resources: sessions
map.resources :users, :has_one => :profile
map.root :controller => "home"
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
КОНТРОЛЛЕР ПРОФИЛЕЙ (по состоянию на 8/20/09, 8 вечера EST)
class ProfilesController < ApplicationController
def index
@users = User.all(:order => "created_at DESC")
end
def show
@user = User.find(params[:user_id])
end
def new
@user.profile = Profile.new
end
def edit
@user = User.find(params[:user_id])
@profile = @user.profile.find(params[:id])
end
def create
@user = User.find(params[:user_id])
@profile = @user.profile.build(params[:profile])
if @profile.save
flash[:notice] = 'Profile was successfully created.'
redirect_to(@profile)
else
flash[:notice] = 'Error. Something went wrong.'
render :action => "new"
end
end
def update
@profile = Profile.find(params[:id])
if @profile.update_attributes(params[:profile])
flash[:notice] = 'Profile was successfully updated.'
redirect_to(@profile)
else
render :action => "edit"
end
end
def destroy
@profile = Profile.find(params[:id])
@profile.destroy
redirect_to(profiles_url)
end
end
Cody, индексная страница ниже бросает следующее исключение:
NoMethodError в профилях # index
Отображение приложения /views/profiles/index.html.erb, где строка # 14 поднята:
undefined метод `name 'для #
<div id="posts">
<% @users.each do |profile| %>
<div class="post">
<div class="left">
<p>Store: </p>
<p>Category: </p>
</div>
<div class="right">
<p><%=h profile.name %></p>
<p><%=h profile.category %></p>
</div>
<div class="bottom">
<p><%= link_to 'Go to profile', user_profile_path(@user, profile) %></p>
<p><%= link_to 'Edit', edit_user_profile_path(@user, profile) %></p>
<p><%= link_to 'Destroy', user_profile_path(@user, profile), :confirm => 'Are you sure?', :method => :delete %></p>
</div>
</div>