0

我是 Rails 的新手(以及一般的编码),我似乎无法弄清楚这种形式有什么问题。

用例:我的网站有多家公司。每个公司可以有多个位置。在公司展示页面上,我需要能够添加/删除位置。

Company Model:
class Company < ActiveRecord::Base
  attr_accessible :company_name, :company_website

  has_many :company_interests
  has_many :interests, through: :company_interests

  has_many :company_locations
  has_many :locations, through: :company_locations

    def add_location!(location)
        company_locations.create!(location_id: location.id)
    end

    def remove_location!(location)
        company_locations.find_by_location_id(location.id).destroy
    end

    def has_location?(location)
        company_locations.find_by_location_id(location.id)
    end
end

定位模型:

class Location < ActiveRecord::Base
  attr_accessible :city
  validates :city, presence: true, uniqueness: true

  has_many :company_locations
  has_many :companies, through: :company_locations 
end

和 CompanyLocation 模型:

class CompanyLocation < ActiveRecord::Base
  attr_accessible :company_id, :location_id

  belongs_to :company
  belongs_to :location
end

在我的公司控制器中,我使所有公司和位置在视图中可用:

def show
    @company = Company.find(params[:id])
    @locations = Location.all
end

在 Show 视图中,我列出了所有位置并显示了一个表单来添加/删除一个位置:

<% provide(:title, @company.company_name) %> 
<div class="row">
    <aside class="span4">
        <section>
            <h1>
                <%= @company.company_name %>
            </h1>
            <p>
                <%= @company.company_website %>
            </p>
            <p>
                <%= link_to "Edit Profile", edit_company_path(@company) %>
            </p>
        </section>
        <section>
            <div>
              <h1>Associations</h1>
              <p>Locations: <%= link_to @company.locations.count, "#" %>
              <p>Interests <a href="#">7</a></p>
            </div>
        </section>
    </aside>
    <div class="span8">
        <h3>Company Locations</h3>
        <ol class="locations">
            <% @locations.each do |location| %>
            <li>
                <span class="locations">
                    <%= location.city %>
                    <div>
                        <% if @company.has_location?(location) %>

                            <%= form_for(@company.company_locations.find_by_location_id(location.id),
                                            html: { method: :delete }) do |f| %>
                            <%= f.submit "Remove", class: "btn btn-large" %>
                            <% end %>
                        <% else %>
                            <%= form_for(@company.company_locations.build(location_id: location.id)) do |f| %>
                                <div><%= f.hidden_field :location_id %></div>
                                <div><%= f.hidden_field :company_id %></div>
                                <%= f.submit "Add", class: "btn btn-large btn-primary" %>
                            <% end %>
                        <% end %>
                    </div>
                </span>
            </li>
            <% end %>
        </ol>
    </div>
</div>

这是 CompanyLocations 控制器:

class CompanyLocationsController < ApplicationController
    def create
    @location = Location.find(params[:company_location][:location_id])
    @company = Company.find(params[:company_location][:company_id])
    @company.add_location!(@location)
    redirect_to @company
  end

  def destroy
        @location = Location.find_by_location_id(params[:company_location][:location_id])
        #@company = Company.find(params[:company_location][:company_id])
        #@company_location = @company.company_locations.find_by_location_id(params[:company_location][:location_id])
        #@company_location = Location.find(params[:company_location][:location_id])
    #@company = Company.find(params[:company_location][:company_id])
    @company.remove_location!(location)
    redirect_to @company
  end
end

添加位置可以正常工作,但是当我尝试删除位置时出现以下错误:

NoMethodError in CompanyLocationsController#destroy
undefined method `[]' for nil:NilClass
app/controllers/company_locations_controller.rb:10:in `destroy'
Parameters:

{"utf8"=>"✓",
 "_method"=>"delete",
 "authenticity_token"=>"CSeDt/aquzCyf55k4Y0Nz6O9/bwWO6gmLrd4dK/Tt08=",
 "commit"=>"Remove",
 "id"=>"1"}

我觉得我不明白如何在表单中调用特定的 companylocation 对象,但我无法弄清楚。请帮忙!

4

1 回答 1

0

从您的错误日志中,您应该能够辨别您从客户端收到的参数,没有像“company_location”=>{'location_id'=> xxx } 这样的参数,但只有 id=>1。

这是您在 form_for 构建器中从 @company.company_locations.find_by_location_id(location.id) 获得的 id。

 <%= form_for(@company.company_locations.find_by_location_id(location.id),
                                        html: { method: :delete }) do |f| %>

正如@meagar 和@MrYoshiji 所说,你需要的只是一个简单的@location = Location.find params[:id]

顺便说一句,你的模态中有很多冗余代码,你不需要像 getter 或 setter 这样的函数

def add_location!(location)
    company_locations.create!(location_id: location.id)
end

def remove_location!(location)
    company_locations.find_by_location_id(location.id).destroy
end

def has_location?(location)
    company_locations.find_by_location_id(location.id)
end

例如,如果您需要添加位置,请在控制器中使用它@company.locations << @location,Rails 会处理其他事情。由于您已经声明了 Company 模型和 Location 之间的关联,因此您无需手动编写辅助函数来完成这项工作。

于 2013-08-12T17:06:35.930 回答