将命名范围与 find_or_create_by 结合使用

发布于 2024-10-11 07:30:43 字数 1037 浏览 5 评论 0原文

我花了一些时间来解决这个问题,但没有看到其他人发表过帖子,所以也许这会对某人有所帮助。另外,我没有太多 Rails 经验,因此我很感激任何更正或建议,尽管下面的代码似乎运行良好。

我已经设置了一个虚拟属性,以便按照 Railscast 中的讨论,从名字和姓氏中获取完整名称虚拟属性。我也想按 full_name 进行搜索,所以我按照

named_scope :find_by_full_name, lambda {|full_name| 
  {:conditions => {:first => full_name.split(' ').first, 
     :last => full_name.split(' ').last}}
}

但是...我希望能够将所有这些用作:find_or_create_by_full_name。使用该名称创建命名范围仅提供搜索(它与上面的 :find_by_full_name 代码相同)——即它不执行我想要的操作。因此,为了处理这个问题,我为我的 User 类创建了一个类方法,名为:find_or_create_by_full_name

# This gives us find_or_create_by functionality for the full_name virtual attribute.
# I put this in my user.rb class.
def self.find_or_create_by_full_name(name)
  if found = self.find_by_full_name(name).first # Because we're using named scope we get back an array
    return found
  else
    created = self.find_by_full_name(name).create
    return created
  end
end

I spent some time figuring this out and haven't seen others post on it so maybe this will help someone. Also, I don't have much Rails experience so I'd be grateful for any corrections or suggestions, though the code below seems to work well.

I've set up a virtual attribute to make full_name out of first_name and last_name as discussed in the Railscast on virtual attributes . I wanted to search by full_name as well so I added a named_scope as suggested in Jim's answer here.

named_scope :find_by_full_name, lambda {|full_name| 
  {:conditions => {:first => full_name.split(' ').first, 
     :last => full_name.split(' ').last}}
}

BUT... I wanted to be able to use all of this as :find_or_create_by_full_name. Creating a named scope with that name only provides searching (it's identical to the :find_by_full_name code above) -- i.e. it doesn't do what I want. So in order to handle this I created a class method for my User class called :find_or_create_by_full_name

# This gives us find_or_create_by functionality for the full_name virtual attribute.
# I put this in my user.rb class.
def self.find_or_create_by_full_name(name)
  if found = self.find_by_full_name(name).first # Because we're using named scope we get back an array
    return found
  else
    created = self.find_by_full_name(name).create
    return created
  end
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

把人绕傻吧 2024-10-18 07:30:43

你也可以只使用
User.find_or_create_by_first_name_and_last_name(:first_name => "firstname", :last_name => "last_name")

You could as well just Use
User.find_or_create_by_first_name_and_last_name(:first_name => "firstname", :last_name => "last_name")

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文