I have 3 models with the following structure:
Application and Photo belongs_to Listing. Listing has_many photos and applications.
class Listing < ActiveRecord::Base
belongs_to :user
has_many :photos
has_many :applications
end
class Application < ActiveRecord::Base
belongs_to :user
belongs_to :listing
end
class Photo < ActiveRecord::Base
belongs_to :listing
end
I'm trying to get the photos of the listings that are associated with a users applications.
I start in the controller by passing all the applications of the current user:
#apps = current_user.applications
In the view I want to display all the photos like this:
<% #apps.each do |app| %>
<%= image_tag app.listing.photos[0].image.url(:thumb) if app.listing.photos.length > 0 %>
<% end %>
But I get this error when trying to render the view:
undefined method `photos' for nil:NilClass
Can't I access the photo that belongs to the listing that belongs to the application with this syntax - app.listing.photos[0].image.url ?
Is it possible that some of your applications are not associated with any listing? If so:
<% #apps.each do |app| %>
<%= image_tag app.listing.photos[0].image.url(:thumb) if app.listing.try(:photos).present? %>
<% end %>
Related
Basically I have 3 different models
class Zone < ApplicationRecord
has_many :providers
end
class Provider < ApplicationRecord
has_many :referrals
belongs_to :zone
end
class Referrals < ApplicationRecord
belongs_to :provider
end
Referrals belong to Providers which then belongs to a Zone. Now the problem im having is counting how many referrals from a zone?
this is the erb tag I tried
<% #zones.each do |z| %>
<li style="color: green">
<%= link_to z.name, z %>
<% z.providers.each do |p| %>
<%= p.referrals.count %>
<% end %>
</li>
<% end %>
But that counts the referrals from each provider and displays it. I want it to just show the total only?
class Zone < ApplicationRecord
has_many :providers
has_many :referrals, through: :providers
end
This will let you do...
z.referrals.count
I have the following models:
Post.rb
has_many :likes
belongs_to :user
Like.rb
belongs_to :user
belongs_to :post
User.rb
has_many :posts
has_many :likes
I'm trying to query the user likes in the view like this:
<% #user.likes.each do |i| %>
<%= i.post.title %>
<% end %>
and it returns undefined method 'title' for nil:NilClass
I only can reach the array of posts like this:
<% #user.likes.each do |i| %>
<%= i.post %>
<% end %>
Or like this <%= #user.likes.first.post.title %>
I can't understand why I can't reach the "title" or any other property.
Any help?
It seems at least one of #user.likes doesn't have its associated post. So Like#post returns nil, and on that nil object you try to call title which raises an error. If this situation is not desired, you probably have to validate likes so that every Like has its post:
class Like < ActiveRecord::Base
# ...
validate :post, presence: true
if so, you probably should also make sure associated likes are destroyed when the post is destroyed:
class Post < ActiveRecord::Base
# ...
has_many :likes, dependent: :destroy
You also can fetch likes only with associated post like this:
<% #user.likes.joins(:post).each do |i| %>
or use try in view, so that when like without post is reached, no error is raised:
<%= i.post.try(:title) %>
If your like always belongs to post, it would be better to have user association with likes using "through: :posts" option. That is correct way of association in this scenario.
So your code will be as follows:
Post.rb
has_many :likes
belongs_to :user
Like.rb
belongs_to :post
User.rb
has_many :posts
has_many :likes, through: :posts
and then you can access user's likes as:
<% #user.likes.each do |i| %>
<%= i.post.title %>
<% end %>
Which will always contain post title.
I have the following setup in my rails app:
A user registers and he chooses from a set of check boxes for Music Styles.
The Music Styles are only 4 right now but should be extendable. I'd like to have a list of MusicStyles that I can extend and change easily.
My approach would be to create a model 'MusicStyles' and a model 'UserMusicStyles' and then use a has_many_through association similar to:
class User < ActiveRecord::Base
has_many :user_music_styles
has_many :music_styles, :through => :user_music_styles
end
class UserMusicStyle < ActiveRecord::Base
belongs_to :user
belongs_to :music_style
end
class MusicStyle < ActiveRecord::Base
has_many :music_styles
has_many :users, :through => :user_music_styles
end
Now, during registration I would do something like MusicStyle.all.each do |m| ... to display the checkboxes but how do I save it to the database correctly in the user controller?
Any help much appreciated!
You can do it like this:
<%= form_for #user do |f| %>
<!-- User stuff -->
...
<% MusicStyle.all.each do |m| %>
<%= check_box_tag('user[music_style_ids][]', m.id, #user.music_styles.include?(m)) %>
<% end %>
<%= f.submit 'Save' %>
<% end %>
I have these models:
class Order < ActiveRecord::Base
has_many :order_lines
has_many :prizes, :through => :order_lines
accepts_nested_attributes_for :order_lines
end
class Prize < ActiveRecord::Base
has_many :order_lines
end
class OrderLine < ActiveRecord::Base
belongs_to :order
belongs_to :prize
end
I would like a nested form in the order form that displays every prize with a text box next to it where the user can enter pieces (eg. the amount to order). When the form is submitted the create action should create the order_lines accordingly. I can't find a solution anywhere.
First of all in the Order model use accepts_nested_attributes_for :prizes, instead of what you have.
After that it's easy, just add a form in the view (there's no additional step controller)
<%= form_for #order do |order_form| %>
..
<%= order_form.fields_for :prizes do |prizes_form| %>
<%= prizes_form.text_field :piece %>
..
<% end %>
..
<% end %>
This is straight from the documentation... You should definitely check that first.
I have a one-to-one relationship between user and goal. I want to build a form that shows the goal of a user. The problem is that my code only works when the user already has a goal defined. The text field is not rendered when no goal is present.
<%= user_builder.fields_for :goal do |goal_builder| %>
<%= goal_builder.text_field :goal %>
<% end %>
Does Rails provide an easy way to do this?
This is how I would do it :
class User < ActiveRecord::Base
has_one :goal
accepts_nested_attributes_for :goal
after_initialize do
self.goal ||= self.build_goal()
end
end
You can do this very easily with accepts_nested_attributes_for.
In the view, as you had:
<%= user_builder.fields_for :goal do |goal_builder| %>
<%= goal_builder.text_field :goal %>
<% end %>
In the User model:
class User < ActiveRecord::Base
has_one :goal # or belongs_to, depending on how you set up your tables
accepts_nested_attributes_for :goal
end
See the documentation on nested attributes, and the form_for method for more information.