Пожалуйста, смотрите ОБНОВЛЕНИЯ внизу вопроса ...
Для справки, эта проблема возникла из-за некоторых исправлений, которые я сделал на основе предыдущей проблемы, с которой я столкнулся здесь: Связывание двух моделей в 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
Когда я нажимаю «отправить», чтобы создать нового пользователя, он теперь отправляет мне следующий URL-адрес, который кажется правильным: localhost: 3000 / users / 6 / profile / new. Но он выдает следующее исключение:
NoMethodError in
ProfilesController # new У вас есть
ноль объект, когда вы этого не ожидали!
Произошла ошибка при оценке
nil.build
Трассировка указывает, что проблема в контроллере профилей в методе New. Контроллер профилей выглядит так:
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
Не удалось найти пользователя без идентификатора
Вот что говорит мне журнал:
Обработка ProfilesController # index
[GET] Параметры:
{ "Действие" => "Индекс",
"controller" => "profile"}
ActiveRecord :: RecordNotFound (Не удалось
найти пользователя без идентификатора):
приложение / контроллеры / profiles_controller.rb: 5: в
`Индекс '
Чтобы дать вам остальную информацию о приложении, модели имеют следующие ассоциации:
Профиль принадлежит _to: пользователь
Пользователь имеет _one: профиль
У меня есть это в файле rout.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, по вашему запросу:
profile / 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 => 'session',: action => 'destroy'
map.login 'login',: controller => 'session',: action => 'new'
map.resources: сеансы
map.resources :users, :has_one => :profile
map.root :controller => "home"
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
КОНТРОЛЛЕР ПРОФИЛЕЙ (по состоянию на 20.08.09, 20:00 EST)
Класс ProfilesController
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
Коди, на индексной странице ниже выдается следующее исключение:
NoMethodError в профилях # index
Отображение app / views / profile / index.html.erb, где поднята строка # 14:
неопределенное имя метода для #
<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>