如何在Rails中为特定客户创建操作项

时间:2014-12-30 03:22:57

标签: ruby-on-rails associations

Rails的新手。 OOP新手。我有一个客户端和action_item模型。动作项(待办事项)有很多并且属于许多客户。客户端有很多动作项。基本上:用户从客户页面创建TODO。

用户:用crud创建一个客户端(Crayola LLC,ex)。 用户随后进入客户的显示页面(Crayola LLC的展示页面)。 我的问题是,如何拥有:用户能够为该客户创建一个操作项。示例:致电Crayola,向他们出售升级版本)。

使用外键client_id和action_item_id创建名为action_items_clients的连接表。跑迁移。根本不知道如何为客户创建行动项目。就目前而言,可以在没有客户的情况下创建操作项。这很简单。这是我的新手对铁路障碍的理解。

行动项目控制器:

类ActionItemsController< ApplicationController中

def index
    @action_items = ActionItem.all


end 

def new
    @action_items = ActionItem.new
end

def create
        @action_item = ActionItem.new(action_items_params)
        if @action_item.save
            redirect_to(:action => 'show', :id => @action_item.id)
            #renders client individual page
        else 
            redirect_to(:action => 'new')
        end
end

def edit
    @action_item = ActionItem.find(params[:id])
end

def update
    @action_item = ActionItem.find(params[:id])
    if @action_item.update_attributes(action_items_params)
        redirect_to(:controller => 'action_items', :action => 'show', :id => @action_item.id)
        flash[:notice] = "Updated"
        else 
            render 'new'

    end 
end


def show
    @action_item = ActionItem.find(params[:id])


end

def action_clients
    @action_clients = ActionItem.Client.new 
end



def delete
    @action_items = ActionItem.find(params[:id])
end

def destroy
    @action_items = ActionItem.find(params[:id]).destroy
    redirect_to(:controller => 'action_items', :action => 'index')
end

private 
def action_items_params
    params.require(:action_item).permit(:purpose, :correspondence_method, :know_person, :contact_name_answer, :additional_notes)
end

客户端控制器

class ClientsController < ApplicationController

def index
@clients = Client.all
end

def new 
@client = Client.new
end

def create
@client = Client.new(clients_params)
    if @client.save
        redirect_to(:action => 'show', :id => @client.id)
        #renders client individual page
    else 
        redirect_to(:action => 'new')
    end

end 

def edit
@client = Client.find(params[:id])
end

def update
@client = Client.find(params[:id])
  if @client.update_attributes(clients_params)
  redirect_to(:action => 'show', :id => @client.id)
else 
  render 'edit'
 end
end

def show
@client = Client.find(params[:id])

end

def delete
@client = Client.find(params[:id])
end

def destroy
@client = Client.find(params[:id]).destroy
redirect_to(:controller => 'clients', :action => 'index')
end

private
def clients_params
params.require(:client).permit(:name)
end


end

显示每个客户的页面:

<div align="center"><h1> <%= @client.name %> </h1></div>

<ol><li><%= link_to('Enter Definition Mode', :controller => 'action_items', :action  => 'new', :id => @client.id) %></br></br></li> 

<li><%= link_to('Back to client List', :controller => 'clients', :action => 'index')  %> </li></br>

</ol>

1 个答案:

答案 0 :(得分:1)

我这样做的方法是设置您的路线,以便action_items嵌套在客户端下,如下所示:

# /clients/13/action_items
resources :clients do
  resources :action_items
end

或者,如果登录的用户是客户端或只有一个客户端,那么您可以跳过它,只需resources :action_items

然后,如果您将用户定向到/clients/13/action_items,则他们会点击action_items#indexparams[:client_id]将设置为13。您可以使用它来控制整个控制器中的action_items。

只要您在ClientActionItem设置之间设置关系:

class Client < ActiveRecord::Base
  belongs_to :user
  has_and_belongs_to_many :action_items
end
class ActionItem < ActiveRecord::Base
  has_and_belongs_to_many :clients
end

将其范围扩展到当前登录的用户可能也很好:

class User < ActiveRecord::Base
  has_many :clients
end

但这取决于你希望事情如何发挥作用。这可能是我构建事物的方式:

class ActionItemsController < ApplicationController
  before_action :get_client

  def index
    @action_items = @client.action_items.all
  end

  def new
    @action_items = @client.action_items.new
  end

  def create
    @action_item = @client.action_items.new(action_items_params)
    if @action_item.save
      redirect_to(:action => 'show', :id => @action_item.id, :client_id => @client.id)
    else 
      redirect_to(:action => 'new')
    end
  end

  # and other actions....

  private

  def get_client
    @client = current_user.clients.find(params[:client_id])
  end
end

编辑(解决一些评论问题):

如果action_items不总是作用于客户端,则它们可以同时存在于嵌套和非嵌套路由下:

# /action_items
resources :action_items

resources :clients do
  # /clients/13/action_items
  resources :action_items
end

然后before_action可以更加通用,将owner设置为客户端或用户本身(只要Userhas_and_belongs_to_many :action_items):

class ActionItemsController < ApplicationController
  before_action :get_owner

  def index
    @action_items = @owner.action_items.all
  end

  # ... other stuff

  private

  def get_owner
    if params[:client_id].present?
      @owner = current_user.clients.find(params[:client_id])
    else
      @owner = current_user
    end
  end
end

您的重定向可能需要考虑它们是否来自嵌套页面,因此您可能会有类似这样的逻辑:

def destroy
  item = @owner.action_items.find(params[:id])
  item.destroy
  if params[:client_id]
    redirect_to client_action_items_path(params[:client_id])
  else
    redirect_to action_items_path
  end
end

你的link_to也必须同样改变,这里是上述销毁行动的链接:

<% if params[:client_id].present? %>
  <%= link_to 'Delete action item', client_action_item_path(params[:client_id], @action_item), :method => 'delete' %>
<% else %>
  <%= link_to 'Delete action item', @action_item, :method => 'delete' %>
<% end %>