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>
答案 0 :(得分:1)
我这样做的方法是设置您的路线,以便action_items嵌套在客户端下,如下所示:
# /clients/13/action_items
resources :clients do
resources :action_items
end
或者,如果登录的用户是客户端或只有一个客户端,那么您可以跳过它,只需resources :action_items
。
然后,如果您将用户定向到/clients/13/action_items
,则他们会点击action_items#index
,params[:client_id]
将设置为13
。您可以使用它来控制整个控制器中的action_items。
只要您在Client
和ActionItem
设置之间设置关系:
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
设置为客户端或用户本身(只要User
也has_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 %>