I am working with a Rails 2.3.9 application and in this case posts are workouts. I am trying to get all comments for the following workouts.
#workouts = Workout.today_only.all(:include => {:user => :memberships}, :conditions => ["workouts.public = '1' AND memberships.box_id = ?", #box.id], :order => "workouts.created_at DESC")
My associations are correct:
Workout has_many :comments
Comment belongs_to :workout
How would I get at list of comments on those specifc workouts ordered by created_at DESC?
Note: today_only is a named_scope and I can post the code if it is relevant.
In your Workout model, add:
has_many :comments, :order => 'created_at DESC'
then you can do:
Workout.today_only.all(:include => [:comments, {:user => :memberships}], ...
Related
So I have a User model, and a Group model which has several users thanks to the GroupUserAssociation model. Here's how my relationships are defined:
class Group < ActiveRecord::Base
has_many :group_users, :class_name => 'GroupUserAssociation', :foreign_key => :group_id
has_many :group_admins, :class_name => 'GroupUserAssociation', :foreign_key => :group_id, :conditions => ['level = 1']
has_many :group_not_admins, :class_name => 'GroupUserAssociation', :foreign_key => :group_id, :conditions => ['level = 0']
has_many :users, :through => :group_users, :source => :user
has_many :admins, :through => :group_admins, :source => :user
has_many :not_admins, :through => :group_not_admins, :source => :user
end
If I want to add/remove users to group, there is an elegant way to write it (elegant because it doesn't involves the GroupUserAssociation object):
Group.first.users << User.first # Adds to group
Group.first.users.delete(User.first) # Removed from group
But if I do
Group.first.admins << User.first
Group.first.admins.delete(User.first)
it also deletes the association (hence has the same effect as the first lines).
Is there an elegant way (without handling the GroupUserAssociation object to promote/demote admin (= to update GroupUserAssociation.level from 1 to 0) ?
I could do
Group.first.users.delete(User.first) # Removed from group
Group.first.admins << User.first
But that would mean 2 times commiting to DB which is not really good...
I read there are some nice things for this in Rails 4, but unfortunately I'm using Rails 3.2...
Thanks
We do this using this code:
#config/routes.rb
resources :entries do
post :category
delete ":category_id", to: :category, as: "remove_category"
end
#Categories
def category
entry = #entry = Entry.find(params[:entry_id])
category = #category = Category.find(params[:category_id])
#Actions
entry.categories << category if request.post? && !entry.categories.include?(category)
entry.categories.delete(category) if request.delete?
#Return
respond_to do |format|
format.html { redirect_to collection_path }
format.js
end
end
I have a User model that has_many parents.
I want that user model to have one father and one mother.
So my class Parent belongs_to user
Currently I have
class User < ActiveRecord::Base
has_many :parents
has_one :father, :class_name => 'Parent', :foreign_key => 'user_id', :conditions => {:type => 'male'}
has_one :mother, :class_name => 'Parent', :foreign_key => 'user_id', :conditions => {:type => 'female'}
end
class Parent < ActiveRecord::Base
belongs_to :user
end
The problem is in my controller.
...
def edit
#user = User.find(params[:id])
#user.mother = Parent.new(:type => 'female')
#user.father = Parent.new(:type => 'male')
...
When I go into the edit, it creates and throws the 2 parents into the database without even having changed anything in the form. For example, when I click edit on a user, I go to the edit page. When I look into the database, they're already created.
My form looks like so:
= form_for #user do |f|
= f.fields_for :father do |father_form|
etc...
= f.fields_for :mother do |mother_form|
etc...
I've tried doing something alone the lines of this in my controller:
...
#user.parents.build(:type => 'male')
#user.parents.build(:type => 'female')
...
But the form doesn't show up.
Any help would be greatly appreciated.
Try to use
#user.build_father(:type => 'male')
#user.build_mother(:type => 'female')
instead of
#user.mother = Parent.new(:type => 'female')
#user.father = Parent.new(:type => 'male')
in your action
Here are my models:
class User < ActiveRecord::Base
...
belongs_to :picture, :foreign_key => 'picture_id',
:class_name => 'UploadedFile',
:dependent => :destroy
has_many :enrolled_groups, :through => :interests
...
end
class Group < ActiveRecord::Base
has_many :enrolled_users, :through => :interests,
:source => :user
end
I want to get an XML feed for my Groups with the enrolled users and their picture information.
The following line works fine (just with the enrolled users):
render :xml => #group.to_xml(:include => [:enrolled_users] )
How can I also include the picture info in the feed? I tried a bunch of things but can't figure it out... any idea?
If doing .to_xml(:include => [:enrolled_users, :picture]) doesn't work, then the hacky way would be to add (in User class):
def attributes
super.merge(:picture => picture)
end
You should be able to access nested resources by something like this:
render :xml => #group.to_xml(:include => [{:enrolled_users => :picture}])
I couldn't get it to work with the other proposed solutions. The way I ended up doing it was as follow:
In the controller:
render :xml => #group.to_xml(:include => {:enrolled_users => {:methods => :picture_url}})
In the model:
def picture_url
HOST+picture.public_filename(:avatar)
end
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.
I installed Sphinx and Thinking Sphinx for ruby on rails 2.3.2.
When I search without conditions search works ok. Now, what I'd like to do is filter by tags, so, as I'm using the acts_as_taggable_on plugin, my Announcement model looks like this:
class Announcement < ActiveRecord::Base
acts_as_taggable_on :tags,:category
define_index do
indexes title, :as => :title, :sortable => true
indexes description, :as => :description, :sortable => true
indexes tags.name, :as => :tags
indexes category.name, :as => :category
has category(:id), :as => :category_ids
has tags(:id), :as => :tag_ids
end
For some reason, when I run the following command, it will bring just one announcement, that has nothing to do with what I expect. I've got many announcements, so I expected a lot of results instead.
Announcement.search params[:announcement][:search].to_s, :with => {:tag_ids => 1}, :page => params[:page], :per_page => 10
I guess something is wrong, and it's not searching correctly.
Can anyone give my a clue of what's going on?
Thanks,
Brian
Thinking Sphinx relies on associations in model. In common situations you only have to put index definition below your associations.
With acts_as_taggable_on plug-in you don't have tag-related associations in model file and when you write
indexes tags.name, :as => :tags
TS interprets it like:
CAST(`announcements`.`name` AS CHAR) AS `tags`
(look at sql_query in development.sphinx.conf, in my case).
I suppose that you have attribute name in model Announcement and don't run into error when rebuild index.
But we expect:
CAST(GROUP_CONCAT(DISTINCT IFNULL(`tags`.`name`, '0') SEPARATOR ' ') AS CHAR) AS `tags`
and:
LEFT OUTER JOIN `taggings` ON (`announcements`.`id` = `taggings`.`taggable_id`)
LEFT OUTER JOIN `tags` ON (`tags`.`id` = `taggings`.`tag_id`) AND taggings.taggable_type = 'Announcement'
To get things working just add tag-related associations in your model before you rebuild index:
class Announcement < ActiveRecord::Base
acts_as_taggable_on :tags,:category
has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "ActsAsTaggableOn::Tagging",
:conditions => "taggings.taggable_type = 'Announcement'"
#for context-dependent tags:
has_many :category_tags, :through => :taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag",
:conditions => "taggings.context = 'categories'"
In define_index method:
indexes category_tags(:name), :as => :tags
has category_tags(:id), :as => :tag_ids, :facet => true
In controller:
#announcement_facets = Announcement.facets params[:search], :with => {:tag_ids => [...]}
#announcements = #announcement_facets.for.paginate( :page => params[:page], :per_page => 10 )
I found that simply defining the index thus:
Class Thing < ActiveRecord::Base
acts_as_taggable
define_index do
..other indexing...
indexes taggings.tag.name, :as => :tags
end
end
worked fine.
One possibility is that you need to declare the type for tag_ids as :multi because TS can get confused (I just discovered this here http://groups.google.com/group/thinking-sphinx/browse_thread/thread/9bd4572398f35712/14d4c1503f5959a9?lnk=gst&q=yanowitz#14d4c1503f5959a9).
But why not use the tag names to search? E.g.,
Announcement.search params[:announcement][:search].to_s, :conditions => {:tags => "my_tag"}, :page => params[:page], :per_page => 10
Or, if you need to search for multiple tags:
Announcement.search( "#{params[:announcement][:search].to_s} (#tags my_tag | #tags your_tag)", :page => params[:page], :per_page => 10 )
(as aside, you may want to sanitize/remove sphinx-control-characters from the user-provided query before using it).
For debugging, I would go into console and strip down your query as much as possible (eliminate pagination arguments, even the query (just do ""), etc.).