在控制器中使用局部变量作为参数

时间:2018-07-25 16:01:38

标签: ruby-on-rails ruby-on-rails-5.2

我遇到了麻烦。我在这里连接了三个模型:用户,列表和假名。本质上,用户可以上传书籍进行销售,但是如果他们想使用其他名称列出书籍,则他们还可以创建假名。

这在“清单”显示页面上很好用。我在控制器中使用它。

@pseudo = Pseudonym.find(@listing.pseudo_id)

然后在显示页面上,我仅使用<%= @pseudo.name %>来显示假名。

这是这两个动作的控制器。

def index
  @pseudo = Pseudonym.find_by(params[:pseudo_id])
  @listings = Listing.all.order
end

def show
  @pseudo = Pseudonym.find(@listing.pseudo_id)
end 

对于上下文,我的假名表仅存储名称,ID和创建它的用户ID。

  create_table "pseudonyms", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "user_id"
    t.index ["user_id"], name: "index_pseudonyms_on_user_id"
  end

用户创建新列表时,会从所有假名的下拉列表中选择假名。

新列表形式

<%= f.collection_select(:pseudo_id, current_user.pseudonyms, :id, :name, prompt: 'Select a pseudonym if you want to use one. Ignore this to use your real name.') %>

我的问题是何时需要在任何索引页上显示假名。当我遍历所有列表时,我不再有权访问@listing.pseudo_id

<% @listings.each do |listing| %>
    <li>
        <%= link_to listing do %>
            <%= image_tag listing.image.url(:thumb), title: listing.title %>
        <% end %>

        <div class="listing_overview">          
            <h2><%= link_to truncate(listing.title, length: 24, separator: ' '), listing_path(listing) %></h2>

            <div id="stars">
                <div class="star-rating" data-score=<%= listing.avg_rating %> style="max-width: 10%; margin-0;"></div>
            </div>

            <%= image_tag(listing.user.image.url, title: listing.user.username) %>

            <% if listing.pseudo_id? %>
                <%= link_to @pseudo.name, user_path(listing.user) %></p>
            <% else %>
                <%= link_to listing.user.name, user_path(listing.user) %></p>
            <% end %>
            <b><%= number_to_currency(listing.price) %></b>
        </div>
    </li>
<% end %>

它起作用,但是,在索引页面上显示了错误的假名。如果用户在数据库中只有一个假名,那就可以了。但是,如果有多个用户,它将显示他们创建的第一个用户。找不到根据ID的假名,该假名必须来自listing.pseudo_id

我在做什么错?

2 个答案:

答案 0 :(得分:1)

如果用户可以定义多个假名,请尝试检查列表中是否包含任何假名:

listing.pseudonyms.any?

,如果是,请遍历它们

listing.pseudonyms.each {|pseudonym| ... }

答案 1 :(得分:0)

所以我设法使它起作用。我的问题是,我以为我可以像link_to路由一样执行控制器参数,从而使事情变得复杂。例如,一个人可能会使用

<%= link_to "Some Page", some_page_path(page.id) %>

我认为我可以将本地变量从列表循环传递回控制器。最终,我最终只是将每个清单的名字都设为化名。

listing.rb

class Listing < ApplicationRecord
  belongs_to :user
  belongs_to :pseudonym, optional: true

pseudonym.rb

class Pseudonym < ApplicationRecord
 belongs_to :user
 has_many :listings

我从列表表中删除了pseudo_id列,仅添加了一个外键来引用假名表。

class AddPseudonymsToListings < ActiveRecord::Migration[5.0]
  def change
    add_reference :listings, :pseudonym, index: true, foreign_key: true
  end
end

现在,没有理由在控制器中提出任何要求。因为此列是可选的,所以有时该列为nil,所以在视图中,我仅指定显示假名(如果存在假名ID),否则仅显示用户名。我只是从这样的视图调用化名:

<% if listing.pseudonym_id? %>
    <%= link_to listing.pseudonym.name, user_path(listing.user) %>
<% else %>
    <%= link_to listing.user.name, user_path(listing.user) %>
<% end %>