我是Rails的新手并且正在构建CMS,并且需要允许用户选择他们拥有的某个餐馆,然后该选择将被传递给部分,而部分将显示属于该餐厅的活动。 。简而言之,我创建的数据模型就是这样:
class User < ActiveRecord::Base
has_many :restaurants, dependent: :destroy
end
class Restaurant < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
has_many :campaigns, dependent: :destroy
end
class Campaign < ActiveRecord::Base
belongs_to :restaurant
end
目前,我有一个show
页面,其中显示所选餐厅的广告系列的部分将显示:
<% provide(:title, @user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
</section>
<section>
<% if @user.locations.any? %>
<div>
<%= link_to "Start a Campaign", newcampaign_path, class: "btn btn-medium btn-primary" %>
</div>
<%= link_to "Manage Locations", uploadlocations_path %>
<% else %>
<%= link_to "Upload Locations", uploadlocations_path, class: "btn btn-medium btn-primary" %>
<% end %>
</section>
<section>
<%# disply list of restaurants%>
<%= link_to "Add New Restaurant", newrestaurant_path, class: "btn btn-medium btn-primary" %>
<ul class ="campaigns">
<%= render @restaurants %>
</ul>
</section>
</aside>
<div class="span8">
<% if @restaurants.any? %>
<ol class="campaigns">
<%= render @campaigns, object: @restaurants %>
</ol>
<% end %>
</div>
</div>
控制器为(尽管不正确):
def show
@user = User.find(params[:id])
@restaurants = @user.restaurants.paginate(page: params[:page])
@campaigns = @restaurants.first.campaigns.paginate(page: params[:page])
end
用户可以在render @restaurants
的侧边菜单中点击特定餐厅,这将转到部分:
<ul>
<span class="content">
<%= link_to restaurant.name, '#' %>
</class>
</ul>
此布局无法正常工作,因为我不知道如何将所选的餐厅信息传回显示页面的标签,以显示所选餐厅的特定广告系列。如何让用户点击菜单中的餐馆并将选定的特定餐厅发回用户<%= render @campaigns, object: @restaurants %>
页面的show
?
答案 0 :(得分:1)
首先,让我给你一些关于Rails Partials的想法。
Rails中的部分内容旨在让您能够将模块化布局样式的HTML附加到页面,而无需不断重写。它基本上就像你的Rails布局的“助手”。
我认为你对Rails部分在前端的工作方式感到困惑。您必须记住,Rails只是在您的浏览器中呈现HTML(尽管使用后端数据支持的对象),因此,您正在调用的partials
除此之外什么都不做。
您需要记住的诀窍是,您的部分应回收页面上特定数量的元素。因此,传递给它们的局部变量/数据在宏观方案中有点无关紧要。
<强>集合强>
我相信你会想要做以下事情:
#app/views/users/show.html.erb
<%= render partial: "restaurants", collection: @restaurant, as: :restaurant %>
#app/views/users/_restuarants.html.erb
<%= content_for :li do %>
<%= link_to restaurant.name, user_restaurants_path(current_user, restaurant) %>
<% end %>
如果您使用适当的路由结构进行备份,它应该适合您:
#config/routes.rb
resources :users do
get :restaurant_id, action: :show, as: :restaurants # -> domain.com/users/:user_id/:restaurant_id
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
user_id = params[:restaurant_id].present? ? params[:user_id] : params[:id]
@user = User.find user_id
@restaurant = @user.restaurants.find params[:restaurant_id] if params[:restaurant_id]
@campaigns = @restaurant.campaigns if @restaurant
end
end
不是我个人做的方式,但它肯定会让您能够在users
展示页面上加载特定餐厅的广告系列。
<强>结构强>
您需要考虑的重要事项是应用程序的结构。
你提到你是Rails的新手 - 让我快速介绍一下基于Rails的应用程序应该如何工作。因为它们是面向对象的,所以您确实需要将流量建立在您将要调用的对象/资源上。
您将从阅读object orientated软件模式中受益 - 您需要确保每次在Rails中加载“视图”时,您使用相对于控制器/模型的对象填充它正在与之合作。
这就是我的意思:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find params[:id]
@restaurants = @user.restaurants
end
end
您是否了解了如何从原始@user
对象构建数据结构?
在设计应用程序的结构时,您需要了解您将在每个视图中显示的数据。具体而言,您需要了解如果您有users#show
的观看次数 - 您的主要关注点是使用相关的User
对象填充该视图
答案 1 :(得分:0)
好吧,如果我理解正确,在左侧菜单中你有一个餐馆列表,在右边菜单中你想要显示所选餐厅的广告系列,对吗?
因此,在餐厅部分,您将需要为该特定餐厅创建链接:
<ul>
<span class="content">
<%# We'll pass the page as well to keep pagination working %>
<%= link_to restaurant.name, user_path(restaurant.user, restaurant_id: restaurant.id, page: params[:page]) %>
</span>
</ul>
也许你会想要使用嵌套资源(我不认为你是在用户控制器中,因为你将user_id作为id),如果你使用的是嵌套资源而且你在餐馆里控制器,路径应该是这样的:user_restaurant_path(restaurant.user,restaurant)
然后在控制器中你找不到你选择的特定餐厅:
def show
@user = User.find(params[:id])
@restaurants = @user.restaurants.paginate(page: params[:page])
@restaurant = @user.restaurants.find_by_id(params[:restaurant_id]) || @restaurants.first #in case no restaurant is selected, like the first time.
@campaigns = @restaurant.campaigns if @restaurant
end