NoMethodError in rails using multiple conditions - ruby-on-rails

I can't seem to get the logic for my conditions to work for this query. I can get #showemail = PreferenceSetting.find(1) to work...but when I try to add conditions, it keeps throwing a "NoMethodError". I am fairly new at rails and am really stuck on this.
def show
#showemail = PreferenceSetting.where('user_id = ?', params[:u]).where('user_preference_id = ?', 1)
end
This is my code for the view
<%= #showemail.prefers %>
Every time I try to access the 'show' view it says "undefined method `prefers'.
My Models
class PreferenceSetting < ActiveRecord::Base
belongs_to :users_preference, inverse_of: :preference_settings
belongs_to :user, inverse_of: :preference_settings
end
class UserPreference < ActiveRecord::Base
has_many :preference_settings, inverse_of: :user_preference
end

find returns an instance whereas your where methods return an ActiveRecord::Relation object.
Adjust the code of your show action like this:
def show
conditions = {user_id: params[:u], user_preference_id: 1}
#showemail = PreferenceSetting.where(conditions).last
# you could also use: PreferenceSetting.find_by(conditions)
end

Related

Is there a Rails active record method I can call to get all #images?

I have these two models:
class Article < ActiveRecord::Base
has_many :images
end
and
class Image < ActiveRecord::Base
belongs_to :article
end
To get all my articles I simply do this:
#article = Article.all.find(params[:id])
Then I do the following to get all images this article has:
#images = Image.where article_id: #article.id
Is there some active record method that I can call to get all my #images, rather than what I have above? I just wonder if there is a better way than what I am doing.
I tried #article.images but it only returned the relation without the data.
Try this :
#article.images.all

Rails association works when it doesnt use an instance variable

I'm getting the strangest error I've seen in Rails so far. In my view, I can print out the email associated with a painting if I find the record directly (e.g. Painting.find(15). But if I try to use an instance variable it errors (e.g #painting).
views/paintings/show.html.erb
<%= Painting.find(15).artist.user.email %> # works
<%= #painting.artist.user.email %> # Error: "undefined method 'user' for nil:NilClass"
controllers/paintings_controller.rb
def show
#painting = Painting.find(15)
end
Models: "users", "artists", "paintings".
A user can be an artist. So a user has_one artist.
An artist has_many paintings.
I think you should add associations. This how they should look like:
class User < ActiveRecord::Base
has_one :artist # it's ok
end
class Artist < ActiveRecord::Base
belongs_to :user # add this
has_many :paintings
end
class Painting < ActiveRecord::Base
belongs_to :artist
end
For me both cases works with this associations.
Use
def show
#painting = Painting.find(15).last
end
Currently the second one is returning a 1 element array, but in order to call a dependent method, you must specify 1 item.

Ruby on Rails: Undefined Method Error with has_one associations

For some reason I'm getting an NoMethodError for some query, which actually works in the rails console.
Code in index.html.erb
#requests.first.acceptance
This is my Error
undefined method `acceptance' for #<ActiveRecord::Relation::ActiveRecord_Relation_Arrangement:0x000000042ceeb8>
These are my Modules.
class Arrangement < ActiveRecord::Base
belongs_to :acceptance
belongs_to :request
belongs_to :offer, inverse_of: :arrangements
end
class Acceptance < ActiveRecord::Base
belongs_to :user, inverse_of: :acceptances
has_one :arrangement
end
class Request < ActiveRecord::Base
belongs_to :user, inverse_of: :requests
has_one :arrangement
end
This is my Controller
def index
#requests = Array.new
for request in current_user.requests do
#requests << Arrangement.where("request_id = ?", request.id)
end
#acceptances = Array.new
for acceptance in current_user.acceptances do
#acceptances << Arrangement.where("acceptance_id = ?", acceptance.id)
end
end
I can't figure out what I've done wrong here. Everything works in the console, though not in the browser.
Arrangement.where("request_id = ?", request.id)
Returns an array-like relation object which may contain multiple records, not just a single record.
However, on this line in your controller
#requests << Arrangement.where("request_id = ?", request.id)
You're adding the relation to your array, so that
#requests.first.acceptance
Returns the relation, instead of the first record.
One way to fix this is to do this in your controller:
#requests = Array.new
for request in current_user.requests do
#requests << Arrangement.where("request_id = ?", request.id).first
end
Solved
I was passing an array in the #requests array in my controller.

Active Relation: Retrieving records through an association?

I have the following models:
class User < ActiveRecord::Base
has_many :survey_takings
end
class SurveyTaking < ActiveRecord::Base
belongs_to :survey
def self.surveys_taken # must return surveys, not survey_takings
where(:state => 'completed').map(&:survey)
end
def self.last_survey_taken
surveys_taken.maximum(:position) # that's Survey#position
end
end
The goal is to be able to call #user.survey_takings.last_survey_taken from a controller. (That's contrived, but go with it; the general goal is to be able to call class methods on #user.survey_takings that can use relations on the associated surveys.)
In its current form, this code won't work; surveys_taken collapses the ActiveRelation into an array when I call .map(&:survey). Is there some way to instead return a relation for all the joined surveys? I can't just do this:
def self.surveys_taken
Survey.join(:survey_takings).where("survey_takings.state = 'completed'")
end
because #user.survey_takings.surveys_taken would join all the completed survey_takings, not just the completed survey_takings for #user.
I guess what I want is the equivalent of
class User < ActiveRecord::Base
has_many :survey_takings
has_many :surveys_taken, :through => :survey_takings, :source => :surveys
end
but I can't access that surveys_taken association from SurveyTaking.last_survey_taken.
If I'm understanding correctly you want to find completed surveys by a certain user? If so you can do:
Survey.join(:survey_takings).where("survey_takings.state = 'completed'", :user => #user)
Also it looks like instead of:
def self.surveys_taken
where(:state => 'completed').map(&:survey)
end
You may want to use scopes:
scope :surveys_taken, where(:state => 'completed')
I think what I'm looking for is this:
class SurveyTaking < ActiveRecord::Base
def self.surveys_taken
Survey.joins(:survey_takings).where("survey_takings.state = 'completed'").merge(self.scoped)
end
end
This way, SurveyTaking.surveys_taken returns surveys taken by anyone, but #user.survey_takings.surveys_taken returns surveys taken by #user. The key is merge(self.scoped).
Waiting for further comments before I accept..

ruby on rails undefined method for array

I have a user who owns many phones
I have a a phone which has many call summaries
therefore my user has many call summaries
Now to the code that I have:
class User < ActiveRecord::Base
has_many :phones
has_many :call_summaries, :through => :phones
end
class Phone < ActiveRecord::Base
belongs_to :user
has_many :call_summaries
end
class CallSummary < ActiveRecord::Base
belongs_to :phones
end
I would like to generate a report that shows all the call summaries for the phones that belong to that certain user. I go into the controller and this is my code there:
def index
#phones = Phone.find(:all, :conditions => ["user_id = ?", #current_user.id])
#call_summaries = #phones.call_summaries.find(:all)
end
But this is returning this error:
undefined method `call_summaries' for #Array:0x476d2d0
Any help would be very much appreciated.
If you have the has_many :through relationship set up, you should just be able to do:
#call_summaries = #current_user.call_summaries
The problem with your method is that you're calling call_summaries on the #phones collection, rather than on individual phone instances.
#phones is an array of Phone objects. You have to iterate through that array and add each phone's call summaries to a single array. Try this:
#phones = Phone.find(:all, :conditions => ["user_id = ?", #current_user.id])
#call_summaries = #phones.inject([]){|arr, phone| arr + phone.call_summaries}
Off topic and just me being fussy, but a dynamic finder is more readable:
#phones = Phone.find_all_by_user_id(#current_user)

Resources