【问题标题】:How to Pass Selected Parameters to Partial如何将选定的参数传递给部分
【发布时间】:2014-11-03 13:32:33
【问题描述】:

我是 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>

目前此布局不起作用,因为我不知道如何将所选餐厅信息传递回显示页面的选项卡以显示所选餐厅的特定广告系列。如何让用户点击菜单中的餐厅,然后将选择的特定餐厅发送回用户show 页面中的&lt;%= render @campaigns, object: @restaurants %&gt;

【问题讨论】:

    标签: jquery ruby-on-rails partials


    【解决方案1】:

    Partials

    首先,让我给你一些关于 Rails Partials 的想法。

    Rails 中的 Partials 旨在让您能够将模块化布局样式的 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 对象填充该视图

    【讨论】:

      【解决方案2】:

      好吧,如果我理解正确的话,在左侧菜单中您有一个餐厅列表,在右侧菜单中您想要显示所选餐厅的广告系列,对吧?

      因此,您需要在餐厅部分中为该特定餐厅创建一个链接:

      <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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-03-02
        • 2011-08-10
        • 1970-01-01
        • 2022-11-24
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多