繁体   English   中英

Ruby on Rails - 将方法的返回值传递给has_attached_file。 我的Ruby语法错了吗?

[英]Ruby on Rails - passing a returned value of a method to has_attached_file. Do I get Ruby syntax wrong?

我正在编写我的第一个RoR应用程序,目前我正致力于允许用户上传图像。 我正在使用Paperclip来达到这个目的。 其中一个步骤涉及将has_attached_file添加到我的模型中:

class MyModel < ActiveRecord::Base
  #...
  has_attached_file :picture, styles: {
    large: "120x150#>", 
    small: "60x75#>"
  }
  #...
end

如果我这样做,一切顺利(或看起来似乎)。 但是我还需要在其他地方访问与整数相同的常量值,所以我添加了一个哈希:

class MyModel < ActiveRecord::Base
  #...
  has_attached_file :picture, styles: {
    large: "120x150#>", 
    small: "60x75#>"
  }
  def picture_sizes
  {
    large: {width: 120, height: 150},
    small: {width: 60, height: 75}
  }
  end
  #...
end

这会产生丑陋的冗余。 所以我想到编写一个从第二个哈希生成第一个哈希的方法,就像这样

class MyModel < ActiveRecord::Base
  #...
  has_attached_file :picture, styles: picture_sizes_as_strings

  def picture_sizes
  {
    large: {width: 120, height: 150},
    small: {width: 60, height: 75}
  }
  end

  def picture_sizes_as_strings
    result = {}
    picture_sizes.each do |label, size|
      result[:label] = "#{size[:width]}x#{size[:height]}#>"
    end
    return result
  end
  #...
end

但这会引发一个错误:

undefined local variable or method `picture_sizes_as_strings' for #<Class:0x007fdf504d3870>

我究竟做错了什么?

has_attached_file在运行时计算。 您已经定义了一个实例方法,但是您没有从实例上下文中调用该方法。

尝试:

def self.picture_sizes_as_strings
  # code here
end

确保使用self.定义另一个方法self.

接着:

has_attached_file :picture, :styles => picture_sizes_as_strings

应该管用。

问题是你试图在类级别上运行的声明( has_attached_image )中使用实例方法picture_sizes_as_strings 这是调用之间的区别

MyModel.picture_sizes_as_strings

MyModel.first.picture_sizes_as_strings

在第一种情况下,我们引用一个类方法(MyModel类本身的方法),在第二种情况下,我们引用一个实例方法(单个my_model对象上的方法)。

首先,您必须通过在self.添加名称前缀来将方法更改为类方法self. ,所以:

def self.picture_sizes
  {
    large: {width: 120, height: 150},
    small: {width: 60, height: 75}
  }
end

现在这还没有完全解决你的问题,因为当ruby首次解析模型时会处理has_attached_image 这意味着它会在你定义self.picture_sizes之前尝试运行has_attached_image ,所以它仍会说undefined method

您可以通过在has_attached_file声明之前放置self.picture_sizes来解决这个问题,但这非常难看。 您也可以将数据放在常量中,但这有其自身的问题。

老实说,没有什么方法可以解决这个问题。 如果是我,我可能会颠倒整个过程,将样式定义为正常,然后使用方法将字符串转换为整数,如下所示:

class MyModel < ActiveRecord::Base
  has_attached_file :picture, styles: {
    large: "120x150#>", 
    small: "60x75#>"
  }

  def numeric_sizes style
    # First find the requested style from Paperclip::Attachment
    style = self.picture.styles.detect { |s| s.first == style.to_sym }

    # You can consolidate the following into one line, I will split them for ease of reading
    # First strip all superfluous characters, we just need the numerics and the 'x' to split them
    sizes = style.geometry.gsub(/[^0-9x]/,'')
    # Next split the two numbers across the 'x'
    sizes = sizes.split('x')
    # Finally convert them to actual integer numbers
    sizes = sizes.map(&:to_i)
  end
end

然后,您可以调用MyModel.first.numeric_sizes(:medium)来查找特定样式的大小,并以数组形式返回。 当然你也可以将它们改成哈希或者你需要的任何格式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM