Im really really new to ruby/ruby on rails and was given a model class that looks like this. I just want ask why is it giving me odd number list for Hash error when I try to call Ranks.search_word("Jagger")
Im using Rails 2.3.5/ActiveRecord 2.3.5
class Ranks < ActiveRecord::Base
set_table_name 'CM_GT_RANK'
set_primary_key 'rank_id'
has_one :character_atlas, :class_name => "CharAtlas", :foreign_key => "char_id_db"
has_one :player_records, :class_name => "PlayerRecord", :foreign_key => "char_id"
default_scope :joins => :character_atlas,
:order => "rank asc"
named_scope :search_word,
lambda{ |keyword|
{
if keyword.present?
{:conditions => { :CM_CHAR_ATLAS => {:char_name => keyword }} }
else
{}
end
}
}
end
You have an additional Pair of curly brackets which are not required. Try:
named_scope :search_word, lambda{ |keyword|
if keyword.present?
{:conditions => { :CM_CHAR_ATLAS => {:char_name => keyword }} }
else
{}
end
}
Related
A bit of difficulty handling multiple children associations for posting to another rails application via Httparty gem.
From the sending application:
:parent has_many :kids
:kid has_many :schools
#parent = Parent(parent_params)
#parent = HTTParty.post("http://localhost:3001/parents/import",
:body => { :parent_id => #parent.id,
:terms_accepted => #parent.terms_accepted,
:email => #parent.email,
:kids => {
#parent.kid.school.name => #parent.kid.school_name,
#parent.kid.age => #parent.kid.age
}
}.to_json,
:headers => { 'Content-Type' => 'application/json' } )
The receiving application has the same relationship
:parent has_many :kids
the combination of array of kids and the use of singular and plural in the post syntax is throwing me off...
The console is showing:
"kids_attributes" => {"0"=>{"age"=>"10", "school_id"=>"8"}, "1"=>{"age"=>"11", "school_id"=>"9"},
Parent has_many Kids, then its expected to have an array here, try the following:
:kids => #parent.kids.map {|kid| {:school_name => kid.school.name, :age => kid.school.age }}
I have this "as_json" method in my Post model:
def as_json(options={})
super(options.merge(:include => { :comments => { :include => [:user] }, :hashtags => {}, :user => {}, :group => {} }))
end
I'd like to set a limit attribute in :comments like this:
def as_json(options={})
super(options.merge(:include => { :comments => { :include => [:user], :limit => 10 }, :hashtags => {}, :user => {}, :group => {} }))
end
but it doesn't work.
How should I proceed?
I think that you have only one possibility.
I suppouse that you have a has_many :comments association in your Post model
So you can define the next has_many association in your Post model, something like this:
has_many :ten_comments, -> { limit(10) }, class_name: "Comment", foreign_key: :post_id
And then you will be able to do this in the as_json method:
def as_json(options={})
super(options.merge(:include => { :ten_comments => { :include => [:user] }, :hashtags => {}, :user => {}, :group => {} }))
end
Sorry for posting four years later, but I hope that someone find useful your question and this answer.
I am using Ruby on Rails 3.0.7 and I would like to DRY (Don't Repeat Yourself) my scope methods.
In the model file I have:
class Articles::Category < ActiveRecord::Base
scope :article_related_to, lambda { |user| where('articles_categories_article_relationships.user_id = ?', user.id) }
scope :comment_related_to, lambda { |user| where('comments_articles_article_category_relationships.user_id = ?', user.id) }
has_many :comment_article_category_relationships
has_many :comments,
:class_name => 'Comments::Articles::ArticleCategoryRelationship',
:through => :comment_article_category_relationships,
:source => :comment
has_many :article_relationships
:class_name => 'Articles::Categories::ArticleRelationship',
has_many :articles,
:through => :article_relationships,
:source => :article
end
By using the above code I can do this:
#comment.article_categories.comment_related_to(#current_user)
#comment.article_categories.article_related_to(#current_user)
How can I "DRY" scopes methods in order to make possible for both :article_related_to and :comment_related_to to use something like the following
#comment.article_categories.related_to(#current_user)
# In order to pass the correct "context" 'article' or 'comment' I thought
# something like
#
# #comment.article_categories.related_to(#current_user, 'article')
# #comment.article_categories.related_to(#current_user, 'comment')
#
# but, maybe, there is a way to retrieve automatically that "context" so to
# write only one "DRYed" scope method.
?
The best I can offer is the following:
scope :related_to, lambda { |user, context|
tbl = context == :article ? :articles_categories_article_relationships
: :comments_articles_article_category_relationships
where("#{tbl}.user_id = ?", user.id)
}
That gives you the #comment.article_categories.related_to(#current_user, :article) like you suggested. But I'm in agreement with Max Williams. This obfuscates your code unnecessarily with no real gain.
If you are really eager to obfuscate your code further you can do this:
def self.method_missing(method, *args)
if method =~ /^(.*)_related_to$/
related_to(*args, $1)
else
super
end
end
def self.related_to(user, context)
through = reflections[context.to_s.pluralize.to_sym].options[:through]
tbl = reflections[through].options[:class_name].underscore.pluralize.gsub('/', '_')
where("#{tbl}.user_id = ?", user.id)
end
Please note that I believe your associations have a couple of typos. Probably should be:
has_many :comment_article_category_relationships,
:class_name => 'Comments::Articles::ArticleCategoryRelationship'
has_many :comments,
:through => :comment_article_category_relationships,
:source => :comment
has_many :article_relationships,
:class_name => 'Articles::Categories::ArticleRelationship'
has_many :articles,
:through => :article_relationships,
:source => :article
In my Rails project I'm using Formtastic to manage my forms. I have a model, Tags, with a column, "group". The group column is just a simple hardcoded way to organize my tags. I will post my Tag model class so you can see how it's organized
class Tag < ActiveRecord::Base
class Group
BRAND = 1
SEASON = 2
OCCASION = 3
CONDITION = 4
SUBCATEGORY = 5
end
has_many :taggings, :dependent => :destroy
has_many :plaggs, :through => :taggings
has_many :monitorings, :as => :monitorizable
validates_presence_of :name, :group
validates_uniqueness_of :name, :case_sensitive => false
def self.brands(options = {})
self.all({ :conditions => { :group => Group::BRAND } }.merge(options))
end
def self.seasons(options = {})
self.all({ :conditions => { :group => Group::SEASON } }.merge(options))
end
def self.occasions(options = {})
self.all({ :conditions => { :group => Group::OCCASION } }.merge(options))
end
def self.conditions(options = {})
self.all({ :conditions => { :group => Group::CONDITION } }.merge(options))
end
def self.subcategories(options = {})
self.all({ :conditions => { :group => Group::SUBCATEGORY } }.merge(options))
end
def self.non_brands(options = {})
self.all({ :conditions => [ "`group` != ? AND `group` != ?", Tag::Group::SUBCATEGORY, Tag::Group::BRAND] }.merge(options))
end
end
My goal is to use Formtastic to provide a grouped multiselect box, grouped by the column, "group" with the tags that are returned from the non_brands method. I have tried the following:
= f.input :tags, :required => false, :as => :select, :input_html => { :multiple => true }, :collection => tags, :selected => sel_tags, :group_by => :group, :prompt => false
But I receive the following error:
(undefined method `klass' for
nil:NilClass)
Any ideas where I'm going wrong?
Thanks for looking :]
I'm not sure we support :group_by with a custom :collection. In fact, that who part of the code was a messy contribution. So, try omitting the :collection for starters, and see where you end up. If there's a bug with Formtastic, please add an issue on Github.
I'd first move your Group class out of this file, and just inherit from where you want, or use a Module in this class. This is the preferred way of getting methods an constants into a class and staying organized.
A really dodgy problem I've got. Here's my model:
class Entry < ActiveRecord::Base
default_scope :order => 'published_at DESC'
named_scope :published, :conditions => ["published_at < ?", Time.zone.now], :order => 'published_at DESC'
belongs_to :blog
end
Now if I do
#entries = Entry.published.paginate_by_blog_id #blog.id,
:page => params[:page],
:order => 'published_at DESC',
It does not return posts unless i move published_at back one hour. BUT:
#entries = Entry.paginate_by_blog_id #blog.id,
:page => params[:page],
:conditions => ["published_at < ?", Time.zone.now],
:order => 'published_at DESC',
And it works fine!
I'm going nuts here, anyone has any ideas of where to even start debugging?
named scopes are not run dynamically, so the Time.zone.now is the value at class load time. If you want the named scope to use a different value with each call, then the conditions need to be the result of a lambda.
Take a look at http://railscasts.com/episodes/108-named-scope and http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality
For example:
named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
This way 1.week.ago is calculated every time the scope is invoked.