【问题标题】:How to access an instance variable from a different controller whose page on which I am rendering a partial?如何从我要在其上呈现部分页面的不同控制器访问实例变量?
【发布时间】:2013-06-15 22:31:09
【问题描述】:

我有一个用户控制器和一个通知控制器。用户 has_many 通知通过许多其他模型。有没有一种好方法可以在我的通知#destroy 操作中定义 @user 以便我可以在我的 javascript 中引用它?

在我的用户显示页面上,我有这样的东西。

users/show.html.erb

<div>

  <div id="user_notificationss_count">
    "You have <%= @user.notifications.count %> notifications"
  </div>

  <%= render @user.notifications %>

</div>

通知/_notification.html.erb

  <div id="notification_<%= @notification.id %>">
    <div>Congrats, you have earned XXX badge!</div>
    <div><%= link_to 'X', notification, method: :delete, remote: true %></div>
  </div>   

users_controller.rb

def show
  @user = User.find(params[:id])
end

notifications_controller.rb

def destroy
  @notification= Notification.find(params[:id])
  @notification.destroy
  respond_to |format|
    format.html { redirect_to :back }
    format.js
  end
end

notifications/destroy.js.erb

$("#notification_<%= @notification.id %>").remove();
$("#user_notifications_count").html("You have <%= @user.notifications.count %> notifications");

在 javascript 中,.remove(); 的第一行可以正常工作。但是,第二行不起作用,因为我没有在控制器销毁操作中定义 @user。我的用户模型 has_many 通知通过多个其他模型。因此,每个通知都没有特定的 user_id。有没有办法从我呈现的 user#show 页面获取 user_id 参数?

对不起,如果我不清楚。请让我知道,我将补充额外的解释/代码。谢谢!


编辑:添加模型代码

user.rb

attr_accessible :name
has_many :articles
has_many :comments
has_many :badges

def notifications(reload=false)
  @notifications = nil if reload
  @notifications ||= Notification.where("article_id IN (?) OR comment_id IN (?) OR badge_id IN (?)", article_ids, comment_ids, badge_ids)
end

article.rb

attr_accessible :content, :user_id
belongs_to :user
has_many :notifications

comment.rb

attr_accessible :content, :user_id
belongs_to :user
has_many :notifications

badge.rb

attr_accessible :name, :user_id
belongs_to :user
has_many :notifications

notification.rb

attr_accessible :article_id, :comment_id, badge_id
belongs_to :article
belongs_to :comment
belongs_to :badge

【问题讨论】:

  • notifications_controller.rb中,有没有办法确定Userhas_many :through的代求模型?
  • 请解释一下用户和通知是如何关联的
  • 嗨@zeantsoi。用户 has_many articles、has_many comments、has_many 'badges. A user can get a notification through only one of these models at a time, so I guess I could do something like if @notification.article_id == nil && @notification.comment_id == nil` 然后 @user = @notification.badge.user 并循环浏览每个场景。不过希望有一个更简单的解决方案。
  • 嗨@Vimsha,我将我的模型添加到我的问题中。
  • @umezo,我认为这可能是最好的方法。实际上,它并没有增加太多逻辑。将此类逻辑抽象到您的模型中以便于使用/重用是明智的。我已经发布了一个答案来演示如何做到这一点。

标签: ruby-on-rails


【解决方案1】:

在您的 Notification 模型中设置一个虚拟属性会起作用:

# app/models/notification.rb
class Notification < ActiveRecord::Base
    belongs_to :article, :comment, :badge

    def user
        if article_id.nil? && comment_id.nil?
            badge.user
        elsif comment_id.nil? && badge_id.nil?
            article.user
        elsif badge_id.nil? && article_id.nil?
            comment.user
        end
    end
end

然后,您可以在通知控制器的 destroy 操作中查找父级:

# app/controllers/notifications_controller.rb
def destroy
    @notification= Notification.find(params[:id])
    @user = @notification.user
    ...
end

您随后将能够访问@user 实例变量,正如您在上面的destroy.js.erb sn-p 中指出的那样。

【讨论】:

  • 像魅力一样工作。顺便说一句,你能想到在通知模型中添加一个 user_id 列并在创建时输入 badge.user.id (或任何相关内容)更好的场景吗?
猜你喜欢
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
相关资源
最近更新 更多