在控制器中调用其他模型中的方法

时间:2016-07-14 13:10:01

标签: ruby-on-rails ruby activerecord

因此,我对卸载功能的概念很陌生,这些功能会将数据库影响到模型而不是控制器,并且难以使其工作。

基本上,在我的Stock控制器中,我试图在User模型中调用方法。相反,我收到了错误:

NoMethodError (undefined method `stock_relationships' for #<Class:0x007fc0da1a8d60>):
  app/models/user.rb:27:in `follow_stock'
  app/controllers/stocks_controller.rb:20:in `add_stock'

所以,这就是我所拥有的:

  

用户在views / stocks / index.html.erb

中添加股票
<% @stocks.each do |s| %>
  <tr>
    <td><%= s.symbol %></td>
    <td><%= s.name %></td>
    <td>
       <%= link_to raw("<i class='fa fa-plus'></i>"), add_stock_path(id: s.id) %>
    </td>
  </tr>
<% end %>
  

然后触发StockController add_stock方法:

def add_stock
    stock = Stock.find(params[:id])
    user = current_user.id
    User.follow_stock(stock_id: stock, user_id: user)
    flash[:success] = "Successfully added stock"
    redirect :back
end
  

方法中的第3行是问题所在,因为follow_stock方法驻留在User模型中:

class User < ActiveRecord::Base

  has_many :stock_relationships
  has_many :stocks, through: :stock_relationships

  def self.follow_stock(stock)
    self.stock_relationships.create(stock_id: stock)
  end
end

有人可以帮助我解决如何实际调用这种方法的问题,还是我完全偏离了我的尝试方式?

更新

我已更改了一些代码,现在我可以创建StockRelationship,但stock_id正在保存为nil

=> #<StockRelationship:0x007fee03f25f00
 id: 17,
 user_id: 1,
 stock_id: nil,
 created_at: Thu, 14 Jul 2016 13:44:52 UTC +00:00,
 updated_at: Thu, 14 Jul 2016 13:44:52 UTC +00:00>

我更改了StockController#add_stock中的代码:

def add_stock
    stock = Stock.find(params[:id])
    current_user.follow_stock(stock)
    flash[:success] = "Successfully added stock"
    redirect_to :back
end

3 个答案:

答案 0 :(得分:0)

stock_relationships是在User的实例上定义的。看起来您正试图在模型中的用户上调用它

self.stock_relationships.create(stock_id: stock)

答案 1 :(得分:0)

你在课堂上调用实例方法,你需要这样的东西。

#user.rb
def follow_stock(stock)
  self.stock_relationships.create(stock_id: stock)
end
#and from controller call it like
user.follow_stock(stock)

现在,您的方法变为实例方法,您可以通过用户类的实例调用它。

答案 2 :(得分:0)

您可以通过重构逐步使代码简洁。

首先,让我们在控制器中编写实现:

def add_stock
  stock = Stock.find(params[:id])
  current_user.stock_relationships.create(stock: stock)
  flash[:success] = "Successfully added stock"
  redirect :back
end

这不是太多的代码,并且足够简洁。在我看来,我不认为代码需要重构,但如果你坚持将逻辑放到User模型来增强表达能力,比如

def add_stock
  stock = Stock.find(params[:id])
  current_user.follow_stock(stock)
  flash[:success] = "Successfully added stock"
  redirect :back
end

然后我们需要实现User#follow_stock。注意我在表示法中使用了#,这意味着follow_stock应该是实例方法,而不是类方法。

class User < ActiveRecord::Base
  def follow_stock(stock)
    stock_relationships.create(user: self)
  end
end

我只是做了一些复制和粘贴(邪恶?不在重构阶段。),并将current_user替换为self,就完成了。