Note that User has many Photos. I'm using the friendly_id gem to generate a slug for photos. This is my Photo model:
class Photo < ActiveRecord::Base
extend FriendlyId
friendly_id :photo_by_author, :use => :slugged
def should_generate_new_friendly_id?
title_changed?
end
def photo_by_author
"#{title} by #{user_id}"
end
belongs_to :user
end
My path is profilename/photos/title, this is my routes.rb
scope ':profile_name' do
resources :photos
end
In my controller, I'm doing #photo = Photo.all.
I'm trying this but isn't working: <a href="<%= photo %>">
How can I do the photos#show path??
Have you try
<% #photo.each do |photo| %>
<%= link_to photo.photo_by_author, photo %>
<% end %>
or
<a href=<%= photo %>" ><%= Photo.first.photo_by_author %></a
>
inside the block
or in your console rails c -s
include Rails.application.routes.url_helpers
default_url_options[:host] = "localhost"
photo_url(Photo.first)
Link_To
Firstly, you shouldn't be trying to populate a "naked" <a> with your ruby variable - you need to use the <%= link_to %> helper:
<%= link_to photo.title, photo_path(photo) %>
The problem is your scope, especially considering this scope is used to determine a variable. I believe the issue is that since Rails expects a variable from this scope, it will not be able to process any of the links without having it
The simple way to resolve that error, as mentioned in the comments,is to populate the route with both values:
<%= link_to photo.title, photo_path(profile_name, photo) %> #-> photo & profile_name need to be declared
You'll want to look up a rake routes to make this work
Friendly_ID
If you want to populate the friendly_id slug values for this route, you'll need to do two things:
Pass the profile_name value as a "slug" (not ID)
Pass the photo object itself
I noticed in the comments, Tiago Farias posted a possible solution for you. If you want that to work with friendly_id, you'll need to pass the photo object without defining the id attribute (this will let friendly_id work its magic)
The next thing you need to consider is that since :profile_name is not tied to any "resource" (controller / model), friendly_id won't be able to populate the name / value that you'd expect. In this case, you need to set the value yourself (by defining it explicitly in your controller)
Related
I want value attribute in the select option menu to contain url's and on click should take to the particular path.I am using helper method to build the path
Code:
<%= select_tag :account, options_from_collection_for_select(Account.all,build_path_for_airline(id),"name") %>
helper:
def build_path_for_airline(id)
new_path = Rails.application.routes.recognize_path(request.path)
new_path[:airline_id] = id
new_path
end
Unfortunately its not working as expected, Can anyone let me know what I am missing here?
According to the documentation, the value_method parameter is exactly that, a method. You can't use an arbitrary block of code and expect it to work.
You should implement your build_path_for_airline as an helper method in your model class, and use that method in the options_from_collection_for_select call.
# app/models/account.rb
class Account
# ...
def airline_path
# Build the airline path for the current account
end
end
# app/views/...
<%= select_tag :account, options_from_collection_for_select(Account.all, :airline_path, :name) %>
Richard-Degenne's answer is correct, but there's an alternative to putting the method in your model. options_from_collection_for_select can also take a lambda for its value_method argument:
<%= select_tag :account, options_from_collection_for_select(
Account.all,
->(account){ build_path_for_airline(account.id) },
"name")
%>
my guides can have many guide_pics. In my show guide view, I want to show the pics. I'm trying to use
<%= image_tag #guide.guide_pics if #guide.guide_pics %>
Instead of the image, the page renders with the text:
So it seems like something is there, I just have to get the picture.
But in the debugger this gives
#<ActiveRecord::Associations::CollectionProxy []>
Does that mean an empty object is returned? If that is the case, maybe I seeded the db wrong:
g1.guide_pics.build(picture: File.open(File.join(Rails.root, '/public/2015-08-28 18.55.47.jpg')))
Otherwise, maybe I set up the association wrong.
My guide_pic model
class GuidePic < ActiveRecord::Base
belongs_to :guide
validates :guide_id, presence: true
validates :picture, presence: true
default_scope -> { order(created_at: :desc) }
end
My guide model
class Guide < ActiveRecord::Base
belongs_to :user
has_many :guide_pics, dependent: :destroy
#mount_uploader :picture, PictureUploader
end
guide_pics is an association, and will return one or more guide_pics.
So you will have to iterate over all guide_pics, as follows:
<% #guide.guide_pics.each do |guide_pic| %>
<%= image_tag guide_pic.picture.url %>
<% end %>
Notice I write guide_pic.picture.url: I am assuming you are using a gem for your attachments, like carrierwave or something similar, which can build a url for your image --if not, you will do add that yourself.
But if you just want to show the first picture, you could do something like
<%= image_tag #guide.guide_pics.first.picture.url if #guide.guide_pics.count > 0 %>
Rails is doing correctly, you are misunderstanding.
while a model is having many pictures (has_many relation) rails is auto-generating a method to access those.
In this case Guide.guide_pics is making a query to the DB, something like
SELECT * from guide_pics where guide_id=5
as you can see - this is selecting all rows, the hole set of data which is associated with one guide. This is what ActiveRecord is called an ActiveRecord::Collection.
First of all, yes, you seeded the DB wrong!. The .build method is not saving anything to the database, you should call the .create method.
If you are having any objects in your database you have 2 (3) ways of rendering the image.
<%= image_tag #guide.guide_pics.first.url if #guide.guide_pics.any? %>
This will take the first picture from the Collection if any is in there.
This is bad code.
another option would be to say .take instead of .first.
better code would be something like
<%= image_tag #guide.preview_picture %>
to do so you need a model function
class Guide
def preview_picture
guide_pics.first.url || "/images/no-logo.jpg"
end
end
this will automatically takes the first picture or returns the string of a default one.
my advise to you: have a look on Carrierwave, Dragonfyl or Paperclip. Thise are awesome FileUploading Gems - fitting your needs.
Look at the documentation of image_tag it expects source of image not collection_proxy You need to iterate the list and show images one by one
<% #guide.guide_pics.each do |pic|%>
<%= image_tag pic %>
<% end %>
Note: pic can be url or name of pic depending on your pics saving technique.
Having trouble understanding how using links_to filter content within the same controller in the rails view works. My code is below:
# index.html.erb (link nav area)
<nav>
<%= link_to 'Daily Monitoring', root_path(:category => "dailymonitoring") %>
<%= link_to 'Smoke Tests', root_path(:category => "smoketests") %>
</nav>
# index.html.erb (cont.)
<ul id="results">
<% if #reportlinks == "dailymonitoring" %>
# dailymonitoring content
<% elsif #reportlinks == "smoketests" %>
# smoketests content
<% end %> <!-- end conditional -->
</ul>
# reports_controller.rb
if params[:category]
#reportlinks = Report.where(:category => params[:category])
else
#reportlinks = Report.all
end
# model (report.rb)
class Report
include ActiveModel::Model
attr_accessor :reports, :smokereports
belongs_to :reports, :smokereports, :reportlinks
end
The error I'm getting is undefined method `belongs_to' for Report:Class and a < top (required) > error. There's no database involved. I'm just trying to make it known that I want to click on any of the links and that filters only the block of content within that if/else statement.
Do I need to create a new controller for the if/else statement to work? Please let me know if more code is needed to get a better understanding. Thanks.
belongs_to is defined in ActiveRecord::Associations, which is part of ActiveRecord. You are manually including ActiveModel::Model which doesn't offer any association-related capabilities.
Includes the required interface for an object to interact with ActionPack, using different ActiveModel modules. It includes model name introspections, conversions, translations and validations. Besides that, it allows you to initialize the object with a hash of attributes, pretty much like ActiveRecord does.
Assuming you don't need the whole ActiveRecord database persistence capabilities but you need the association style, then you'll need to deal with that manually.
Therefore, you will have to define your own methods to append/remove associated records and keep track of them.
The association feature of ActiveRecord is strictly tied with the database persistence.
I've been looking for a solution for a few days, in a Rails 4.1 app, so here is my question :
In a Rails app, I have my model User and Adress.
class User < ActiveRecord::Base
has_many :adresses
accepts_nested_attributes_for :adresses
class Adress < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user
In my form, I make a form_tag for User, no problem.
But, how I can display to the final user, in a form, 2 adresses fields?
I use <%= f.fields_for :adress %> to display one, it's ok. But if I display two forms (so the user can enter 2 adresses) they have both the same name and the request post only keep one.
I read the doc at http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
but, still, I don't get it.
Is there a proper way to do it?
Thanks
I would suggest you to prepare two addresses in new action, add them to the use and then in the form reneder it with foreach.
I found this kind of solution here : http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
Since you have multiple addresses I think foreach is way to go.
So, to help anyone who is noob in Rails and stuck the same way I was :
In your controller :
#user = User.new
#user.adresses = Adress.new, Adress.new
In your view, form :
<%= form_for #user do |f| %>
<%= f.fields_for :adresses do |a| %>
<%= wp.text_field :name %>
<% end %>
<% end %>
will print the name field for adress two times.
(thanks again to #NickCatib)
I have a model that has a main_image per asset and in the attachment model this can only have one true value per asset. I am wondering if there is a way to pull this record without looping through every record to see if main_image is set to true or false.
Clarification:
I can find the value by using the following code:
<% #asset.attachments.each_with_index do |attachment, i| %>
<%= image_tag(attachment.attachment.s_640_480) if !attachment.main_image.nil? && attachment.main_image%>
<%end%>
but, I am wondering how to do this without a loop...
I don't know how to clarify any more...but something like:
<%= image_tag(#attachment.where_main_image.s_640_480) %>
I know that won't work but basically that is the concept
<%= image_tag(#asset.attachments.find_by_main_image(true).attachment.s_640_480) %>
It's not so nice to have this code in your view, so I'd recommend to put it in an instance method of your asset model:
class Asset < ActiveRecord::Base
has_many :attachments
def main_image
attachments.find_by_main_image(true).attachment.s_640_480
end
end
Then in your view you can do:
<%= image_tag(#asset.main_image) %>
You probably have to add some checks that objects are not nil. Good luck.
You can join it up like so:
class Asset < ActiveRecord::Base
has_many :attachments do
def main_image
where(:main_image => true).first
end
end
end
Use in your views like so:
<%= image_tag #asset.attachments.main_image.s640_480 %>
If i understant you need to find some entries in database if the value of it is true or false right ?
So you need to make a method inside your model or use a find with condition in the controller, you can find all what you want inside the documentation.