通过rails中的两个不同控制器创建连接表记录

时间:2014-06-15 13:40:28

标签: ruby-on-rails controller nested-attributes jointable

我试图通过轨道中的替代控制器来了解将记录添加到连接表的最佳方法。

我的应用程序中有各种各样的模型需要这样,但是在我将方法转录到其他方法之前,我首先关注这两个模型,所以应该以此为例。我有VenueInterest模型,它们通过VenuesInterests模型连接(它有一些额外的可选属性,因此不是HABTM关系)。用户可以管理场地实例和/或兴趣实例,因此应该能够选择场所以附加到兴趣,同样可以选择兴趣附加到场地。这应该通过Interest实例视图上的Add Venues链接和Venue实例视图上的Add Interests链接来完成。然后,这将使用户获得相关实例的列表,以便他们选择他们想要选择的实例。

以下是我的模特:

Venue.rb

class Venue < ActiveRecord::Base


has_many :interests, through: :venue_interests
    has_many :venues_interests, dependent: :destroy

    accepts_nested_attributes_for :venues_interests, :allow_destroy => true

end

Interest.rb

class Interest < ActiveRecord::Base

has_many :venues, through: :venue_interests
    has_many :venues_interests, dependent: :destroy

end

VenuesInterests.rb

class VenuesInterest < ActiveRecord::Base

    belongs_to :interest
belongs_to :venue
validates :interest_id, presence: true
validates :venue_id, presence: true

end

这一切似乎都很好,但它是我努力奋斗的控制者和观点。我尝试在场地控制器中添加一个额外的方法add_interest来完成VenuesInterests控制器中创建方法的工作,这样当将场所添加到兴趣时会有一个不同的视图。将兴趣添加到场地,否则我不知道如何做到这一点。我目前的Venues控制器如下:

VenuesController.rb:

class VenuesController < ApplicationController
before_filter :authenticate_knocker!, only: [:new, :edit, :create, :update, :destroy]

respond_to :html, :json

def index
    @venues = Venue.all.paginate(page: params[:page]).order('created_at DESC')
end

def show
    @venue = Venue.find(params[:id])
    @hash = Gmaps4rails.build_markers(@venue) do |venue, marker|
        marker.lat venue.latitude
        marker.lng venue.longitude
        marker.infowindow venue.name
    end
end

def new
    @venue = Venue.new
end

def edit
    @venue = Venue.find(params[:id])
end

def create
    @venue = current_knocker.venues.create(venue_params)
    respond_to do |format|
        if @venue.save!
            format.html { redirect_to @venue, notice: 'Venue was successfully created.' }
            format.json { render json: @venue, status: :created, location: @venue }
        else
            format.html { render action: "new" }
            format.json { render json: @venue.errors, status: :unprocessable_entity }
        end
    end
end

def update
    @venue = Venue.find(params[:id])
    @venue.update_attributes(venue_params)
    respond_to do |format|
        if @venue.update_attributes(venue_params)
            format.html { redirect_to(@venue, :notice => 'Your Venue was successfully updated.') }
            format.json { respond_with_bip(@venue) }
        else
            format.html { render :action => "edit" }
            format.json { respond_with_bip(@venue) }
        end
    end
end

def destroy
end

def add_interests
    @venues_interests = VenuesInterest.new
    @interests = Interests.all.paginate(page: params[:page]).order(:name)
end

private

def venue_params
    params.require(:venue).permit(:admin... etc)
end

end

目前我还没有工作,因为我不确定如何引用控制器中的其他类,但我想知道的重要事情是有更好的方法来执行此操作或我(有点)走在正确的轨道上吗?如果有人有一个好的方法(也许是一个jQuery插件)允许多个选择的视图实例,那也会很棒!

1 个答案:

答案 0 :(得分:1)

在我看来,我会利用现有的update方法来增加兴趣与场地之间的关系。我可以这样做:

def update
    @venue = Venue.find(params[:id])
    @venue.update_attributes(params[:venue_params])
    if params[:interest_ids].present?
       @venue.interests = Interest.where(id: params[:interest_ids])
       @venue.save
    end
   #more code to handle the rendering
end