I currently have this scope:
class User
has_many :inbox_messages, :through => :message_users do
def unread
published.where(:message_users => { :sender => false, :trash => false , :deleted => false}).where(MessageUser.arel_table[:read_at].not_eq(nil))
end
end
end
And it's working. But I was wondering if there is way to merge the second where into the first one.
If I understand your code correctly, you should be able to do that with
published.where(:message_users => { :sender => false, :trash => false , :deleted => false, :read_at => nil })
Related
I'm using the RABL gem to render JSON user data for users of comments which are children of annotations which are children of images. I'd like to do something similar to:
object #image
node :annotations do
#image.annotations.map { |a| {
:id => a.id,
:x1 => a.x1,
:x2 => a.x2,
:y1 => a.y1,
:y2 => a.y2,
node :comments do
#image.annotations.comments.map { |c| {
:body => c.body,
:user_id => c.user_id,
:name => User.find(c.user_id).name,
:user_icon => user_icon(User.find(c.user_id), 'square', 30)
}}
end
}}
end
I know this isn't valid in RABL, I also tried using child instead of node, but couldn't access the user data that way. How should I go about doing this and whats the proper syntax to make this happen?
I got this answer from #calvin-l. The trick was to just map the a.comments then grab the data from each comment that way:
node :annotations do
#image.annotations.map { |a| {
:id => a.id,
:x1 => a.x1,
:x2 => a.x2,
:y1 => a.y1,
:y2 => a.y2,
:comments => a.comments.map { |c| {
:body => c.body,
:created_at => c.created_at,
:user => {
:id => c.user.id,
:facebook_id => c.user.facebook_id,
:name => c.user.name,
:username => c.user.username
}
}}
}}
end
Using rails 3 and acts_as_paranoid. I want to make sure that every task has a comment.
How can I bypass this one validation (check_if_notes) if mark_completed_and_msg is called?
EDIT - Is this the right way?
task.rb
has_one :comment, :as => :commentable
attr_accessor :force_task
# original was - before_update, :check_if_notes
validate :check_if_notes, :on => :update, :unless => proc { |a| a.force_task }
def mark_completed_and_msg(user_id, msg)
Comment.create!(:commentable_type => self.class, :commentable_id => self.id, :content => msg )
self.update_attributes(:completed_by => user_id, :deleted_at => Time.now, :force_task => true)
end
def check_if_notes
if self.comment.blank? || self.comment.content.blank? || self.comment.content.scan(/[\w-]+/).size <= 2
saved = false
self.comment.errors[:content] << "You must have a comment and more than 3 words."
raise ActiveRecord::Rollback
end
end
I think you meant using == in your Proc.
:unless => proc { |a| a[:force_task] == true }
You can also use
:unless => proc { |a| a.force_task? }
I have three models (simplified here):
class Child < ActiveRecord::Base
has_many :childviews, :dependent => :nullify
has_many :observations, :through => :childviews
end
class Childview < ActiveRecord::Base
belongs_to :observation
belongs_to :child
end
class Observation < ActiveRecord::Base
has_many :childviews, :dependent => :nullify
has_many :children, :through => :childviews
end
I'm sending this to some JavaScript using Rails' to_json method like this:
render :layout => false , :json => #child.to_json(
:include => {
:observations => {
:include => :photos,
:methods => [:key, :title, :subtitle]
}
},
:except => [:password]
)
This works perfectly. Observations are retrieved fine 'through' the join table (childviews).
However, I also want to get at data that sits in the childviews join table; specifically the value for 'needs_edit'.
I can't figure out how to get at this data in a to_json call.
Can anyone help me? Many thanks in advance.
qryss
Not sure, but shouldn't this work?
#child.to_json(
:include => {
:observations => {
:include => :photos,
:methods => [:key, :title, :subtitle]
},
:childviews => { :only => :needs_edit }
},
:except => [:password]
)
EDIT:
This might work too, since childviews belongs_to the overvation:
#child.to_json(
:include => {
:observations => {
:include => { :photos, :childviews => { :only => :needs_edit } }
:methods => [:key, :title, :subtitle]
}
},
:except => [:password]
)
Thanks to Rock for the pointers - I now have it working!
This code:
#child.to_json(:include =>
{
:observations => {
:include => {
:photos => {},
:childviews => {:only => :needs_edit}
},
:methods => [:S3_key, :title, :subtitle]
}
},
:except => [:password]
)
gives me this output (abbreviated for clarity):
{
"child":
{
"foo":"bar",
"observations":
[
{
"foo2":"bar2",
"photos":
[
{
"foo3":"bar3",
}
],
"childviews":
[
{
"needs_edit":true
}
]
}
]
}
}
Thank you, Rock! That was doing my head in.
:)
qryss
I want to add a has_many through association to a activerecord model class for each symbol in an array. for example
PeopleOrganisation::ROLES.each do |role|
has_many role.to_s.pluralize.to_sym, :through => :people_organisations, :source => :person,
:conditions => "people_organisations.role = '#{role.to_s}'" do
def << (object)
PeopleOrganisation.send(:with_scope, :create => {:role => **role**}) { self.concat object }
end
end
end
everything works fine except for the reference to the role variable inside the method def. This is because the method def is not a closure. Is there a way of achieving what I want?
Try this:
PeopleOrganisation::ROLES.each do |role|
has_many(role.to_s.pluralize.to_sym,
:through => :people_organisations, :source => :person,
:conditions => ["people_organisations.role = ?", role]
) do
define_method("<<") do |object|
PeopleOrganisation.send(:with_scope, :create => {:role => role}) {
self.concat object
}
end
end
end
Instead of defining method using def you can try define_method method:
PeopleOrganisation::ROLES.each do |role|
has_many role.to_s.pluralize.to_sym, :through => :people_organisations, :source => :person,
:conditions => "people_organisations.role = '#{role.to_s}'" do
define_method(:<<) do |object|
PeopleOrganisation.send(:with_scope, :create => {:role => role}) { self.concat object }
end
end
end
I have a model Vote, and I'm using an after_validation callback.
class Vote < ActiveRecord::Base
after_validation :destroy_reciprocal_votes
belongs_to :voteable, :polymorphic => true
belongs_to :voter, :polymorphic => true
private
def destroy_reciprocal_votes
votes = Vote.delete_all(:vote => false, :voteable_type => "Recipe", :voteable_id => self.voteable_id, :voter_type => "User", :voter_id => self.voter_id)
end
end
You can see that in my method destroy_reciprocal_votes, I called self.voteable_id and self.voter_id, why does this return nil? and how should I retrieve my id's here?
When I do it in console it works fine:
>> voteable_id = "3"
>> voter_id = "162"
>> Vote.delete_all(:vote => false, :voteable_type => "Recipe", :voteable_id => voteable_id, :voter_type => "User", :voter_id => voter_id)
You don't have to refer to id as long as you specify an association. Try this:
Vote.delete_all(:vote => false, :voteable_type => "Recipe", :voteable_id => voteable, :voter_type => "User", :voter_id => voter)
Update
Changed to :voteable_id => voteable.