嵌套对象has_one关系

时间:2016-01-22 20:09:53

标签: ruby-on-rails ruby ruby-on-rails-4 web

我是关于rails的新手,我试图用2个对象和has_one关系做一个crud,我有一个Project和Album,只有一个:name属性。但是当我创建一个项目时,两个名字都是空白的。这是我的代码:

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(项目)

<%= 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

提交表格

    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 %>

当我创建项目时/ new不起作用,但如果我创建相册/新专辑获得名称。

编辑(解决方案)

我的代码是在数据库中插入正确的东西,但我无法在我的项目中显示视图。所以,为了工作,我的projects_controller看起来像这样:

  def show
    @project = Project.find(params[:id])
    @album = Album.take
  end

  def create
    @project = Project.new(project_params)
  end 

为了显示项目:project.find解析的视图上的名称,我发现Album.take here并且它可以显示相册:同一视图上的名称。

Obs:take方法检索没有任何隐式排序的记录。 Obs2:show view保持不变。

1 个答案:

答案 0 :(得分:3)

create行动中,您需要执行以下操作:

def create
 @project = Project.new project_params
 # Don't need to create dependent objects

 respond_to do |format|
    if @project.save
      ...

您不需要单独创建album;所有其他代码看起来应该工作。如果没有,您需要在表单中发布提交的参数(我可以写一个更新)。

-

<强>更新

要在视图中显示albums,您只需要调用关联方法:

#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 %>