Rails 4 - 多态关联和实例

Rails 4 - Polymorphic Associations & instances

我正在 Rails 4.

制作应用

我有一个地址模型,它是多态的。

我的联想是:

profile.rb

has_many :addresses, as: :addressable

address.rb

 belongs_to :addressable, :polymorphic => true

在我的 address.rb 中,我有一个方法用于:

def country_name
    self.country = ISO3166::Country[country]
    country.translations[I18n.locale.to_s] || country.name
  end

在我的个人资料视图文件夹中,我有部分显示用户的国家/地区,如:

<span class="profilesideinfo">
    <% if @addresses.country_name.present? %>
        <%= @addresses.country_name.titlecase %> 
    <% else %>
        <span class="profileeditlink">
            <%= link_to "Add your location", new_address_path %>
        </span>
    <% end %>       
</span>

我也试过:

<% if @profile.addresses.country_name.present? %>
        <%= @profile.addresses.country_name.titlecase %> 
    <% else %>
        <span class="profileeditlink">
            <%= link_to "Add your location", new_address_path %>
        </span>
    <% end %>   

而且我也尝试过(将 country_name(这是我模型中的方法)更改为国家(这是我地址中的属性 table))

我卡住了,因为我可以成功创建一个地址,但是那个国家名称应该显示在配置文件显示部分中。它没有。相反,我收到一条错误消息:

undefined method `country_name' for nil:NilClass

为了在父级中显示对多态实例的引用,是否还需要发生其他事情。

任何人都可以看到需要发生什么才能让它工作吗?

我已经尝试在我的配置文件模型中创建一个范围:

Profile.joins(:addresses).where("addresses.profile_id = ?", profile_id)

我不确定这是否增加了任何价值。我不确定如何使用它或它是否有效,因为地址模型没有 profile_id.

的外键

当我保存并尝试重新加载页面时,我收到了这个错误:

undefined local variable or method `profile_id' for #<Class:0x007fbacaec2d18>

采纳 SurreyMagpie 下面的建议,我将偏音更改为:

<% if @profile.addresses.country_name.any? %>
        <%= @profile.address.country_name.first.titlecase %> 
    <% else %>
        <span class="profileeditlink">
            <%= link_to "Add your location", new_address_path %>
        </span>
    <% end %>

我正在检查是否有任何地址,然后显示第一个国家名称。

当我尝试这个时,我得到这个错误:

undefined method `country_name' for #<ActiveRecord::Associations::CollectionProxy []>

关联的多态性不对您的困难负责。

当您将 country_name 定义为地址 class 中的方法时,这称为实例方法。因此,您可以在单个地址对象上调用它。因此,如果在 rails 控制台中您 运行 Address.first.country_name 您应该收到该特定地址实例的结果。

但是,当您查询 has_many 关联时,在您的情况 @profile.addresses 中,您会得到 ActiveRecord::Associations::CollectionProxy 返回,即使只有一个地址记录。它不完全是一个数组,但具有非常相似的行为。

重点是:您不能一次对整个集合调用您的实例方法。您需要遍历集合并在每个实例上调用该方法。例如:

<% if @profile.addresses.any? %>
  <% @profile.addresses.each do |address| %>
    <span class="profilecountry">
      <%= address.country_name.titlecase %>
    </span>
  <% end %>
<% else %>
  <span class="profileeditlink">
    <%= link_to "Add your location", new_address_path %>
  </span>
<% end %>

可能正是您所需要的 - 尽管您选择显示多个国家/地区的方式取决于您。