在控制器中使用局部变量作为参数
Using a local variable as a param in the controller
我遇到了麻烦。我在这里连接了三个模型:用户、列表和假名。从本质上讲,用户可以上传书籍进行销售,但他们也可以创建假名,以防他们想以不同的名字列出一本书。
这在列表显示页面上效果很好。我在控制器中使用它。
@pseudo = Pseudonym.find(@listing.pseudo_id)
然后在show page我直接用<%= @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
对于上下文,我的假名 table 仅存储名称、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
当用户创建新列表时,他们 select 从他们所有化名的下拉列表中选择化名。
新列表形式
<%= 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
。
我做错了什么?
如果用户可以定义多个假名,请尝试检查列表是否有任何假名:
listing.pseudonyms.any?
如果是,迭代它们
listing.pseudonyms.each {|pseudonym| ... }
所以我设法让它发挥作用。我的问题是我认为我可以用与 link_to 路由相同的方式来处理控制器参数,这让事情变得复杂了。例如,可以使用
<%= link_to "Some Page", some_page_path(page.id) %>
我想我可以将列表循环中的局部变量传递回控制器。最终,我只是让每个列表 belongs_to 成为化名。
listing.rb
class Listing < ApplicationRecord
belongs_to :user
belongs_to :pseudonym, optional: true
pseudonym.rb
class Pseudonym < ApplicationRecord
belongs_to :user
has_many :listings
我从列表 table 中删除了 pseudo_id 列,并简单地添加了一个外键来引用假名 table。
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 %>
我遇到了麻烦。我在这里连接了三个模型:用户、列表和假名。从本质上讲,用户可以上传书籍进行销售,但他们也可以创建假名,以防他们想以不同的名字列出一本书。
这在列表显示页面上效果很好。我在控制器中使用它。
@pseudo = Pseudonym.find(@listing.pseudo_id)
然后在show page我直接用<%= @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
对于上下文,我的假名 table 仅存储名称、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
当用户创建新列表时,他们 select 从他们所有化名的下拉列表中选择化名。
新列表形式
<%= 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
。
我做错了什么?
如果用户可以定义多个假名,请尝试检查列表是否有任何假名:
listing.pseudonyms.any?
如果是,迭代它们
listing.pseudonyms.each {|pseudonym| ... }
所以我设法让它发挥作用。我的问题是我认为我可以用与 link_to 路由相同的方式来处理控制器参数,这让事情变得复杂了。例如,可以使用
<%= link_to "Some Page", some_page_path(page.id) %>
我想我可以将列表循环中的局部变量传递回控制器。最终,我只是让每个列表 belongs_to 成为化名。
listing.rb
class Listing < ApplicationRecord
belongs_to :user
belongs_to :pseudonym, optional: true
pseudonym.rb
class Pseudonym < ApplicationRecord
belongs_to :user
has_many :listings
我从列表 table 中删除了 pseudo_id 列,并简单地添加了一个外键来引用假名 table。
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 %>