I think I'm getting this issue because my Child Class can belong to one Parent or the other Parent but not both. Let me show you my code and then the error.
class Purchase < ActiveRecord::Base # my child class
# columns = user_id, price_id and unit_price_id
belongs_to :user
belongs_to :price
belongs_to :unit_price
scope :today, lambda { joins(:unit_price, :price).
where(:price => { :date => Date.today },
:unit_price => { :date => Date.today } ) }
def total
self.price.sum(:amount) + self.unit_price.sum(:amount)
end
end
And than I try to do this in my view:
<%= number_to_currency(current_user.purchases.today.map(&:total)) %>
But this gives me the error:
PGError: ERROR: missing FROM-clause entry for table "price"
LINE 1: ...s"."price_id" WHERE "purchases"."user_id" = 3 AND "price"."d...
^
: SELECT "purchases".* FROM "purchases" INNER JOIN "unit_prices"
ON "unit_prices"."id" = "purchases"."unit_price_id"
INNER JOIN "prices" ON "prices"."id" = "purchases"."price_id"
WHERE "purchases"."user_id" = 3 AND "price"."date" = '2012-08-16'
AND "unit_price"."date" = '2012-08-16'
I really don't know exactly what its saying here but have an idea which is that the price_id is nil. Is this correct? If so how do I fix this issue? Should I create two seperate purchase models called PricePurchase and UnitPricePurchase as a fix?
Let me know what you think.
Thank you.
Tables aren't aliased and their names are in plural (prices, not price in WHERE), so perhaps this change would help:
where(:prices => { :date => Date.today },
:unit_prices => { :date => Date.today } ) }
Related
I recently updated my Rails app from 4.0 to 4.1. Everything seems to work fine, except this one line in my Resource_Tag Model that was working before.
Essentially, I want to search/find District_Resources by Tag Name and by the District_Resource Name.
**ex.**
If I search the word "Tutoring"
*I should get all District_Resources with the Resource_Tag "Tutoring"
*And all District Resources that include the word Tutoring in it's Name.
(i.e Tutoring Services)
For some reason, I keep getting this error:
wrong number of arguments (1 for 0)
all(:conditions => (string ? [cond_text, *cond_values] : []))
CONTROLLER
class ResourceTagsController < ApplicationController
def index
if params[:search].present?
#Calls Search Model Method
#resource_tags = ResourceTag.search(params[:search])
#tagsearch = ResourceTag.search(params[:search])
#tag_counts = ResourceTag.count(:group => :name,
:order => 'count_all DESC', :limit => 100)
else
#resource_tags = ResourceTag.all
end
end
end
MODELS
class DistrictResource < ActiveRecord::Base
has_many :district_mappings, dependent: :destroy
has_many :resource_tags, through: :district_mappings
accepts_nested_attributes_for :resource_tags
end
class ResourceTag < ActiveRecord::Base
#create relationships with all resource and mapping models
has_many :district_mappings, dependent: :destroy
has_many :district_resources, through: :district_mappings
#I GET AN ERROR HERE
def self.search(string)
return [] if string.blank?
cond_text = string.split(', ').map{|w| "name like ?"}.join(" OR ")
cond_values = string.split(', ').map{|w| "%#{w}%"}
all(:conditions => (string ? [cond_text, *cond_values] : []))
end
end
VIEWS
<%= form_tag(resource_tags_path, :method => 'get', class: "navbar-search") do %>
<form>
<%= text_field_tag :search, params[:search], :class => "search-query form-control" %>
<%= submit_tag "Search", :name => nil, :class => "search-button" %>
</form>
<% end %>
After an hour search I came to know that In rails 4.1 onward all method of ActiveRecord does not take any parameters that's why extra argument error occurs. You can try where instead. Here is your search method
def search(string)
return [] if string.blank?
cond_text = string.split(', ').map{|w| "name like ?"}.join(" OR ")
cond_values = string.split(', ').map{|w| "%#{w}%"}
self.where(string ? [cond_text, *cond_values] : [])
end
User has_many products
Product belongs_to user
User also has an active_account and created_at column in its table.
I am trying to translate this into a query:
'What products exist where the user that the product belongs to has an active account OR is less than 25 days old?'
This is what I have so far (not sure how to add in the OR less than 25 days old):
Product.joins(:user).where(users: {active_account: true})
A better way is to use Arel
users = Arel::Table.new(:users)
products = Arel::Table.new(:products)
users
.join(products,Arel::Nodes::InnerJoin)
.on(users[:id].eq(products[:user_id]))
.where(users[:active_account].eq(true).or(users[:created_at].lt(25.days.ago))
I would start with something like this:
Product.joins(:user).where(
"users.active_account = :account_active OR users.created_at >= :max_age",
{ :account_active => true, :max_age => 25.days.ago }
)
In a next step I would move that logic into scopes and merge that scopes:
# in user.rb
scope :active, ->{
where("users.active_account = :account_active OR users.created_at >= :max_age", { :account_active => true, :max_age => 25.days.ago })
}
# in product.rb
scope :with_active_user, ->{ joins(:user).merge(User.active) }
What allows you to use it like this:
Product.with_active_user
Try this:
Product.joins(:user).where("users.active_account = ? OR users.created_at >= '#{(Time.now - 25.days).utc.iso8601}'", true)
I'm looking to create a "related posts" section, but cheating a little by just displaying the next 6 posts in the series on my show.html.erb
How would I go about showing these?
Thanks,
Jon
EDIT - ADDED POST MODEL
class Post < ActiveRecord::Base
has_and_belongs_to_many :categories
belongs_to :user
is_impressionable :counter_cache => true, :column_name => :view_count
acts_as_taggable_on :tags
extend FriendlyId
friendly_id :title, use: :slugged
scope :featured, -> { where(:featured => true) }
scope :recent, -> { order(created_at: :desc) }
scope :hot, -> { order(view_count: :desc) }
scope :longest, -> { order(duration: :desc) }
def self.sort_by(sort_param)
case sort_param
when 'recent'
recent
when 'hot'
hot
when 'longest'
longest
else
recent
end
end
end
You didn't post the code for your Post model, but assuming it has a posted_at attribute and #post is currently displayed, you can do:
Post.where.not(id: #post.id).order('posted_at desc').limit(6)
I've got app with model where prescriptions are connected with medicines via relations table.
I use one form to create one prescription with 5 relations which contains information about medicine_id, amount, daily and so on. However, medicine table has got a lot more information and thats what I would like to use when validating.
For example - I want to check if field dose from table medicines is like `'%pills'. If so, I would like to do some calculation to check if an amount that user put during filling the form is in range (lets say 30-40 is only correct for this specific medicine)
My relation model:
class Relation < ActiveRecord::Base
belongs_to :prescription
belongs_to :medicine
validates :amount, numericality: {only_integer: true, :greater_than_or_equal_to => 1 }
validates :daily, numericality: {only_integer: true, :greater_than_or_equal_to => 1 }
validates :period_in_days, numericality: {only_integer: true, :greater_than_or_equal_to => 1 }
validate :amount_limit, :if => :pills_form?
private
def amount_limit
end
def pills_form
end
end
How can I get these informations that are in the medicine table when Im validating relations? Or is there any other, more proper way of doing this?
Aswer thanks to the #BroiSatse
class Relation < ActiveRecord::Base
belongs_to :prescription
belongs_to :medicine
validates :amount, numericality: {only_integer: true, :greater_than_or_equal_to => 1 }
validates :daily, numericality: {only_integer: true, :greater_than_or_equal_to => 1 }
validate :amount_limit, :if => :pills_form?
private
def amount_limit
max_amount = self.daily * 90
in_box_amount = medicine.cardinality.scan(/\d+/).first
sum = self.amount * in_box_amount.to_i
if sum > max_amount
errors.add(:amount, "An amount of medicine cannot exceed 90 days of treatment.")
end
end
def pills_form?
pill_form_array = ['plaster' , 'globul', 'czop', 'guma', 'tablet', 'pastyl', 'kaps', 'lamel']
pill_form_array.any? { |item| medicine.form =~ /#{item}/ }
end
end
I am trying to create a query that finds all the Posts that belong to the same Topic id. I believe I'm on the right track, but all #posts returns is every post in the database.
Topics controller:
def show
#topic = Topic.find(params[:id])
#title = #topic.name
#posts = Post.where('topic' == #topic).order("updated_at").page(params[:page]).per(10) #not working. still just fetches all posts
respond_with(#posts)
end
Topic model:
class Topic < ActiveRecord::Base
has_many :posts, :dependent => :destroy
attr_accessible :name
end
Post model:
class Post < ActiveRecord::Base
belongs_to :topic, :touch => true
accepts_nested_attributes_for :topic
attr_accessible :name, :title, :content, :topic, :topic_attributes
end
I would recommend you to use the association in the model to get all the posts. you could do it like this:
def show
#topic = Topic.find(params[:id])
#title = #topic.name
#posts = #topic.posts.order("updated_at").page(params[:page]).per(10)
respond_with(#posts)
end
You can use the ActiveRecord association to do this:
def show
#topic = Topic.find(params[:id])
#title = #topic.name
#posts = #topic.posts
respond_with(#posts)
end
And if you are going to use 'where' you should use it like this:
Post.where('topic_id' => #topic.id)
This is because topic refers to the activerecord association. But how its stored in the db level is different.
whats inside where is 'almost' sql.