代码之家  ›  专栏  ›  技术社区  ›  Andrew

轨道型号:名称-名字、姓氏

  •  7
  • Andrew  · 技术社区  · 15 年前

    我对Rails还比较陌生,正在开发一个Rails3应用程序,为用户提供一个配置文件模型。

    在配置文件模型中,我希望有一个“name”条目,并且我希望能够使用简单的语法访问它的逻辑变体,例如:

    user.profile.name = "John Doe"
    user.profile.name.first = "John"
    user.profile.name.last = "Doe"
    

    这是可能的吗,还是需要将“名字”和“姓氏”作为此模型中的字段?

    4 回复  |  直到 12 年前
        1
  •  16
  •   Mischa    13 年前

    有可能,但我不推荐。

    我会坚持的 first_name last_name 如果我是你,添加一个方法 fullname :

    def fullname
      "#{first_name} #{last_name}"
    end
    

    编辑:

    如果你 真想 user.profile.name ,您可以创建一个 Name 模型如下:

    class Name < ActiveRecord::Base
      belongs_to :profile
    
      def to_s
        "#{first} #{last}"
      end
    end
    

    这允许您执行以下操作:

    user.profile.name.to_s  # John Doe
    user.profile.name.first # John
    user.profile.name.last  # Doe
    
        2
  •  8
  •   Community Mohan Dere    9 年前

    其他答案都是正确的,只要他们忽略了 #composed_of 聚合器:

    class Name
      attr_reader :first, :last
    
      def initialize(first_name, last_name)
        @first, @last = first_name, last_name
      end
    
      def full_name
        [@first, @last].reject(&:blank?).join(" ")
      end
    
      def to_s
        full_name
      end
    end
    
    class Profile < ActiveRecord::Base
      composed_of :name, :mapping => %w(first_name last_name)
    end
    
    # Rails console prompt
    > profile = Profile.new(:name => Name.new("Francois", "Beausoleil"))
    > profile.save!
    
    > profile = Profile.find_by_first_name("Francois")
    > profile.name.first
    "Francois"
    

    如第页的composed_所述,必须分配聚合器的新实例:不能仅替换聚合器中的值。Aggregator类充当一个值,就像一个简单的字符串或数字。

    我昨天也发了一封回复,回复非常类似: How best to associate an Address to multiple models in rails?

        3
  •  3
  •   Chris    12 年前

    正如东京上尉所说,这是一个可怕的想法,但你可以这样做:

    rails g model User full_name:hash
    

    然后您可以这样在其中存储数据:

    user = User.new
    user.full_name = {:first => "Forrest", :last => "Gump"}
    

    现在你的问题开始了。

    若要搜索字段,需要同时搜索两个名称,并且不能像搜索具有相同姓氏的所有人一样进行部分搜索。最糟糕的是你能储存的 任何东西 在场上!所以假设另一个程序员错误地输入了一个字段名,所以在一周内,您有:first=>“name”,:last=>“last”插入到数据库中!哦哦哦哦哦哦!

    如果使用正确的字段名,可以执行以下操作:

    user = User.new(:first_name => "First", :last_name => "Last")
    

    易于阅读,不需要散列。既然你知道如何用错误的方式去做,那就用正确的方式去做吧。:)

        4
  •  2
  •   PeterWong    15 年前

    仅供参考(假设您有一个字段 fullname . 你的 profile.name = "John Doe" )

    class Profile
      def name
        @splited_name ||= fullname.split # @splited_name would cache the result so that no need to split the fullname every time
      end
    end
    

    现在,您可以这样做:

    user.profile.fullname   # "John Doe"
    user.profile.name.first # "John"
    user.profile.name.last  # "Doe"
    

    注意以下情况:

    user.profile.fullname = "John Ronald Doe"
    user.profile.name.first  # "John"
    user.profile.name.second # "Ronald"
    user.profile.name.last   # "Doe"
    

    我同意东京船长的意见。你不会错过中间名的。 此外,此方法假定没有输入中文、日文名称。这是因为这些名字通常在名字和姓氏之间没有空格。