Retrieving first part of two-part params[:id] in rails - ruby-on-rails

I'm sure this has been answered before but I've looked everywhere, so I apologize in advance. When I run:
<%= params %>
I get back: {"controller"=>"spree/taxons", "action"=>"show", "id"=>"women/long-sleeve"}
I'm trying to access the :id in the show action of the taxons controller. I have:
def show
#taxon_id = params[:id]
end
This assigns 'women/long-sleeve' to #taxon_id.
Is there a way to retrieve only 'women' from 'women/long-sleeve'.
I would like to render a partial based on this, something like:
<% if #taxon_id == params[:id] %>
<%= render 'shared/#{#taxon_id}' %>
<% end %>
But instead of rendering 'shared/women' it's trying to render 'shared/women/long-sleeve', which isn't a partial.
Thank you.

If you just want "women" from your params hash then you can do
#taxon_id = params[:id].split("/").first

I would just split on / and grab the first element in the resulting array:
params[:id].split('/').first

If it's always going to be in that format you can change your route:
match '/spree/taxons/:id/:slug' => 'taxons#show'
And your :id field will match correctly.

Related

Linking to the latest post from home page in a Rails application

I'm building a Rails app where I have individual entries called films. I would like to display the latest entry's link on the homepage (separate controller) and I'm struggling to make it work.
My films_controller.rb is as follows (excerpt):
def show
#film = Film.find(params[:id])
end
My home_controller.rb only has the following:
def index
end
And my view file (index.html.erb) has the following:
<%= link_to #film.last.filmTitle, film_path(#film) %>
I'm getting the following error:
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
With the #film.find(params[:id]) highlighted.
Thanks!
The last method:
Find the last record (or last N records if a parameter is supplied). If no order is defined it will order by primary key.
source
You can add a #last_film instance variable in your index controller and use it in the view.
def index
#films = Film.all
#last_film = Film.last
end
and in your index.html.erb
<%= link_to #last_film.filmTitle, film_path(#last_film) %>
The index method need something, currently, it didn't connect with ActiveRecord like model or table, that's why
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
So if you need to show recent posts in the index then you could something like this
def index
#films = Film.limit(10).order(created_at: :desc) #=> or you can use id
end
it will show last 10 records, for this in the index.html.erb like this
<% #films.each do |film| %>
<%= link_to film.filmTitle, film_path(film) %>
<% end %>
In the other hand if you need to show only one post which is the last then you should modify this query like this like limit(10) to limit(1) or you can use use the last method like this
def index
#film = Film.last
#or
##films = Film.limit(1).order(created_at: :desc) #=> or you can use id
end
if you use this #film = Film.last then your index file will like this
<%= link_to #film.filmTitle, film_path(#film) %>
otherwise, you need to use each method which describes before.

Getting the string from a rails pluck to display n

got a super quick question. I'm still new to rails and tried following these two questions but they didn't work for me:Why does Array.to_s return brackets? and ruby 1.9 how to convert array to string without brackets.
I'm trying to show the last message and the date in which it was sent out in my chatroom application. I am able to get the results using this code, but it has brackets around it and I would like to have those brackets removed. Any help here would be amazing, I've attached a screenshot as well. Thank you so much!
Show.html.erb
For the Date:
<%= chatroom.messages.last(1).pluck(:created_at) %>
For the Last Message in Chatroom:
<%= chatroom.messages.last(1).pluck(:body) %>
DirectMessages Controller
class DirectMessagesController < ApplicationController
before_action :authenticate_user!
def show
users = [current_user, User.find(params[:id])]
#messageduser = User.find(params[:id])
#chatroom = Chatroom.direct_message_for_users(users)
#chatroomall = current_user.chatrooms
#messages = #chatroom.messages.order(created_at: :desc).limit(100).reverse
#messagelast = #chatroom.messages.last(1)
last_message = #chatroom.messages.last
render "chatrooms/show"
end
private
def chatroomuserlocator
#chatroomlocator = Chatroom.find(params[:chatroom_id])
end
end
Try this:
<%= chatroom.messages.last.created_at %>
And this:
<%= chatroom.messages.last.body %>
Keep in mind that pluck returns an array, so that would explain your brackets.
I don't think you need pluck here since you are just accessing an attribute on a single item.
If you're not too worried about memory usage, you can fetch the whole object and only access the fields you want.
<%= chatroom.messages.last.created_at %>
<%= chatroom.messages.last.body %>
You can assign the lookup to a value, so it doesn't run twice:
last_message = chatroom.messages.last
Then you can access the attributes efficiently:
last_message.created_at
last_message.body
If you are interested in limiting the attributes or last_message, use select:
last_message = chatroom.messages.select(:created_at, :body).last
Putting it all together:
<% last_message = chatroom.messages.select(:created_at, :body).last %>
<%= last_message.created_at %>
<%= last_message.body %>

Ruby on Rails: Find a record by an attribute not an id

I'm very new to rails so please be patient with me.
In short I'm trying to create a form in which guests to a wedding can enter a simple code (invite_code) and then RSVP. The from should take the invite_code and then take the use straight to the correct invites#show view.
So far so good, but I'm stuck trying to get rails to find a record by something other than and id, I want to find by invite_code. Say I've got an Invite with an id of 4 and an invite_id of 1234, the form is finding the correct record when I enter '4' into the from but not '1234'. Here's some code to explain:
routes.rb
get 'invites/search', to: 'invites#show', controller: :invites
form
...
<%= form_tag invites_search_path, method: :get do %>
<%= label_tag :invite_code, "#" %>
<%= text_field_tag :invite_code, nil %>
<%= submit_tag "Search", name: nil %>
<% end %>
...
invites_controller
...
def show
if params.has_key?(:invite_code)
#invite = Invite.find(params[:invite_code])
else
#invite = Invite.find(params[:id])
end
end
...
rake routes output
Prefix Verb URI Pattern Controller#Action
info_index GET /info/index(.:format) info#index
invites GET /invites(.:format) invites#index
POST /invites(.:format) invites#create
new_invite GET /invites/new(.:format) invites#new
edit_invite GET /invites/:id/edit(.:format) invites#edit
invite GET /invites/:id(.:format) invites#show
PATCH /invites/:id(.:format) invites#update
PUT /invites/:id(.:format) invites#update
DELETE /invites/:id(.:format) invites#destroy
invites_search GET /invites/search(.:format) invites#show
root GET / info#index
URL example
.../invites/search?utf8=%E2%9C%93&invite_code=1234
"utf8"=>"✓", "invite_code"=>"1234", "id"=>"search"
The application seems to be ignoring the invite_id part of if statement in the controller...
Any help appreciated, it's taken me a long time to get this far...
You've got a couple of options. find_by_invite_code will return you the first match:
Invite.find_by_invite_code(params[:invite_code]) # First match or nil
While where will give you all the matches as an Array
Invite.where(invite_code: params[:invite_code]) # Array of matches. May be empty
You can also use the following syntax for find_by:
Invite.find_by(invite_code: params[:invite_code]) # First match or nil
find uses id field by default, use where instead
if params.has_key?(:invite_code)
#invite = Invite.where(invite_code: params[:invite_code]).first
...
def show
if params.has_key?(:invite_code)
#invite = Invite.find_by(invite_code: params[:invite_code])
# find_by argument: value
# returns first match or nil
# same as find, where find searches by id
# Invite.find_by_invite_code params[:invite_code] is deprecated
else
#invite = Invite.find params[:id]
end
end
...

Rendering rails partial with dynamic variables

I'm trying to render a partial based on the taxon the user is inside. In my application.html.erb layout I have the following line of code:
<%= render 'spree/shared/women_subnav' if #enable_women %>
In the taxons controller, inside the show method, I have:
#taxon_id = params[:id].split('/').first
And in taxons#show I have:
<% if #taxon_id == params[:id].split('/').first %>
<%= "#enable_#{#taxon_id}" = true %>
<% end %>
When I run this I get a SyntaxError. But in taxons#show If I just enter:
<% if #taxon_id == params[:id].split('/').first %>
<%= "#enable_#{#taxon_id}" %>
<% end %>
without the '= true' then the page renders, outputting '#enable_women'. So I know it's getting the correct variable, I just need that variable to be set to true. What am I missing?
Thanks so much.
First of all I would like to give you some heads-up:
calling first on a user submittable input is not a great idea (what if I submit ?id=, it would return nil) also non utf-8 encoding will crash your app such as: ?id=Ж
Controllers are beast! I see you are setting the value of a true/false instance_variable in the view, please use controllers do define the logic before rendering its output. especially when parameter dependant.
so for a solution:
in your controller as params[:id] should suggest an INT(11) value:
def action
# returning a Taxon should be a good idea here
#taxon = Taxon.find(params[:id])
# as I would give a Taxon class an has_many relation to a User
#users = #taxon.users
end
and in your action's view
<%= render :partial => "taxons/users", collection: #users %>
of course you would have the great ability to scope the users returned and render the wanted partial accordingly.
if you want more info about "The Rails way" please read:
http://guides.rubyonrails.org/
Have fun!
use instance_variable_set
instance_variable_set "#enable_#{#taxon_id}", true
just a reminder that it's better to do these things inside a controller.

Render a rails partial based on the id of an action

I'm building a small ecommerce site that sells a variety of mens and womens clothing. i would like to render a partial based on which taxonomy the user is in. For example, if the user is at mysite.com/t/women/pants I would like to render _women.html.erb, or, if the user is at mysite.com/t/men/shirts I would like to render _men.html.erb.
I have a Taxonomy model that has_many taxons, and the Taxon model has_many products.
In taxons_controller.rb I have:
def show
#taxon = Taxon.find_by_permalink(params[:id])
return unless #taxon
#taxonomy = Spree::Taxonomy.all
#taxon_title = Spree::Taxon.all
#searcher = Spree::Config.searcher_class.new(params.merge(:taxon => #taxon.id))
#searcher.current_user = try_spree_current_user
#searcher.current_currency = current_currency
#products = #searcher.retrieve_products
respond_with(#taxon)
end
And in taxons#show I have: (which I know is wrong)
<% #taxon_title.each do |title| %>
<% #taxonomy.each do |taxonomy| %>
<% if title.name == taxonomy.name %>
<%= render "spree/shared/#{title.name.downcase}" %>
<% end %>
<% end %>
<% end %>
When I go to mysite.com/t/women/long-sleeve the rails debugger displays :
controller: spree/taxons
action: show
id: women/long-sleeve
How do I access the id of the action im inside, so that in the controller/view I can do something like:
'if id equals 'women' render "spree/shared/#{title.name.downcase}"'
where title is the name of the taxonomy?
I imagine I need to find(params[:something] in the show action of the controller, but I'm a little unclear about params.
*
*
*
#beck03076 That's a great trick. Thank you very much. But it's still not working.
In my controller I put:
#taxon_id = Spree::Taxon.find(params[:id])
Then in the action I put:
render 'spree/shared/women' if #taxon_id == params[:id]
And when I load the page it says 'the page you were looking for doesn't exist'. My partial is in the correct directory. Is my syntax correct?
My params are:
{"controller"=>"spree/taxons", "action"=>"show", "id"=>"women/long-sleeve"}
Thanks again for your help!
Whenever you are unclear about params, just put the lines below in the action and execute the action.
p "****************************"
p params
p "****************************"
Now, goto the terminal in which you started your server.
Locate those two "*******" and everything thats in between them are params.
params is basically a ruby hash.
example:
params look like this, {:controller => "hello",:action => "bye", :id => 7, :others => "OK"}
In your controller to access the id, use params[:id].(=7)
to access others, use params[:others].(="OK")

Resources