【问题标题】:Rails 4 execute associated model method from controllerRails 4 从控制器执行关联的模型方法
【发布时间】:2015-03-12 20:25:01
【问题描述】:

假设我们有一个代码:

型号:

class Dog < ActiveRecord::Base
  def self.make_noise
    puts 'bow-wow'
  end
end

控制器:

class DogsController < ApplicationController
  def index
    Dog.make_noise
  end
end

这可行,但我更愿意编写控制器 index 方法代码,例如:AssociatedModel.make_noiseModel.make_noise

是否可以在 Rails 中调用关联的模型方法而不在代码中使用其类名?

如果我想使用继承并让 PetsController 成为所有宠物的基础(或每个适用的控制器都包含 PetNoise Concern)并在那里声明索引方法,这将很有用。

我不确定我是否解释得足够好。

好的。一种方法(我不喜欢)是这样写PetsController 方法:

def index
  params[:controller].classify.constantize.make_noise
end

这样,如果我从DogsController 继承PetsController,它仍然可以工作,而无需在DogsController 中定义单独的索引。但也许还有其他更巧妙的解决方案。

【问题讨论】:

  • 所以...您想在对象上调用方法...而不知道对象是什么?对不起,我不明白,你得再解释一下。我的意思是,您可以将模型分配给一个变量(本质上是对象指针)并在其上调用一个方法。那是你要的吗?必须有人知道self.model 是什么。
  • 对不起,这个例子是错误的,我当然不是指实例方法,而是类方法。

标签: ruby-on-rails ruby


【解决方案1】:

正如我在this answer 中所解释的,您可以使用params[:controller] 确定模型。像这样:

params[:controller] # => "dogs"
params[:controller].classify # => "Dog"

因此,您可以像这样“一般”地编写索引操作:

def index
  model_class = params[:controller].classify.constantize
  model_class.make_noise
end

【讨论】:

  • 是的,就是这样,但有没有更好的解决方案(我真的不喜欢params[:controller] 部分)或者它是唯一的解决方案吗? params[:controller] 对于关联的型号名称是否总是正确的?
  • @user2041318 不确定您所说的“更好”解决方案是什么意思。你可以根据类名来做,这在 IMO 中更加混乱。例如。继承资源 gem 使用 self.class.name.sub(/Controller$/, '').singularize
  • 我只是希望有一些像self.modelname 这样的简短替代方案,但也许没有这样的东西。无论如何,感谢您的澄清。
  • 正如这里所解释的blog.littleimpact.de/index.php/2008/08/13/constantize-with-care constantize 可能很危险,但对于params[:controller] 来说似乎没问题
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多