Reputation: 31
I'm new on rails , im trying to do a crud with 2 objects and has_one relation, I have a Project and Album , and just a :name property for each one. But when I create a project, both names are blank. here's my code:
project.rb , album.rb
class Project < ActiveRecord::Base
has_one :album
accepts_nested_attributes_for :album, allow_destroy: true
end
class Album < ActiveRecord::Base
belongs_to :project
end
ProjectsController.rb
def new
@project = Project.new
@album = @project.build_album
end
def create
@project = Project.new
@album = @project.create_album(params[:album])
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: @project }
else
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
def project_params
params.require(:project).permit(:name, album_attributes: [:name])
end
_form.html.erb (project)
<%= form_for(@project) do |f| %>
<% if @project.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@project.errors.count, "error") %> prohibited this project from being saved:</h2>
<ul>
<% @project.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name, 'Project name: ' %><br>
<%= f.text_field :name %>
</div>
<%= f.fields_for :album do |a| %>
<div class="field">
<%= a.label :name, 'Album name' %><br />
<%= a.text_field :name %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
routes.rb
resources :projects do
resources :albums
end
SUBMITED BY THE FORM
Started POST "/projects" for ::1 at 2016-01-22 18:39:16 -0200
Processing by ProjectsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"asJbsifN/NB2/LGY0xb8S0+OnsRlJMJqhVe3vUOzEyLPAMQN1VFcDiFOwSNcXu+V1wZ78obnc6uaacCzxDdW8A==", "project"=>{"name"=>"test", "album_attributes"=>{"name"=>"test"}}, "commit"=>"Create Project"}
(0.2ms) begin transaction
SQL (0.3ms) INSERT INTO "projects" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "test"], ["created_at", "2016-01-22 20:39:16.515028"], ["updated_at", "2016-01-22 20:39:16.515028"]]
SQL (0.1ms) INSERT INTO "albums" ("name", "project_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "test"], ["project_id", 7], ["created_at", "2016-01-22 20:39:16.517545"], ["updated_at", "2016-01-22 20:39:16.517545"]]
(0.6ms) commit transaction
Redirected to http://localhost:3000/projects/7
Completed 302 Found in 7ms (ActiveRecord: 1.3ms)
my projets/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Project Name:</strong>
<%= @project.name %>
</p>
<p>
<strong>Album Name:</strong>
<%= @project.album.name %>
</p>
<%= link_to 'Edit', edit_project_path(@project) %> |
<%= link_to 'Back', projects_path %>
When i create the project/new don't work, but if i create album/new the album get a name.
EDIT (Solution)
My code was inserting the right things on database, but i could not show in my projects show view. So, for work my projects_controller looked like this:
def show
@project = Project.find(params[:id])
@album = Album.take
end
def create
@project = Project.new(project_params)
end
For show the project :name on the view the project.find resolves, and i found that Album.take here and it works to show the album :name on the same view.
Obs: The take method retrieves a record without any implicit ordering. Obs2: the show view stay the same.
Upvotes: 2
Views: 69
Reputation: 76784
In your create
action, you need to do as follows:
def create
@project = Project.new project_params
# Don't need to create dependent objects
respond_to do |format|
if @project.save
...
You don't need to separately create album
; all the other code looks like it should work. If it doesn't, you will need to post the submitted params from your form (to which I'll be able to write an update).
--
Update
To show the albums
in the view, you just need to call the associative method:
#app/controllers/projects_controller.rb
def show
@project = Project.find params[:id]
end
#app/views/projects/show.html.erb
<% @project.albums.each do |album| %>
<%= album.title %>
<% end %>
Upvotes: 3