I want to create helper that return the avatar linked to the user.
for that i do:
<%= basic_avatar(user)%>
and the helper:
def basic_avatar(user)
link_to image_tag(user.avatar) ,'#', :title => user.name
end
But now, i want to add some options like attributes, classes etc.
for example, i want to do this:
<%= basic_avatar(user, class: 'avatar')%>
or:
<%= basic_avatar(user, class: 'avatar', name: 'avatar')%>
Just add an options hash to helper declaration, and use that when making your image tag. The last argument in the image_tag call is a hash, so you're basically all set.
def basic_avatar(user, options={})
link_to image_tag(user.avatar), "#", options.merge(:title => user.name)
end
This makes it so the options is optional, and then they just get passed along to image_tag, as well as the title you want.
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")
%>
I have a simple self method defined in my model.
def self.search(name, type)
#handle name
#handle type
end
My confusion is with regards to the view & controller. Passing the correct values (or using the correct syntax).
In the view, a simple form.
<%= form_tag(index_path, method: :get) do %>
<%= label_tag :type, 'Type' %>
<% type_array = ["Foo", "Foo_One", "Foo_Two", "Foo_Three"] %>
<%= select_tag :type, options_for_select(type_array, selected: params[:type]), include_blank: true %>
<%= label_tag :name, 'Name' %>
<% name_array = ["Foo", "Foo_One", "Foo_Two", "Foo_Three"] %>
<%= select_tag :name, options_for_select(name_array, selected: params[:name]), include_blank: true %>
<%= submit_tag "Filter" %>
<% end %>
Confusion One
Under options_for_select, should it be select_tag :search or select_tag :type? Should it be selected: params[:search] instead??
In the controller
def index
#foo = Foo.all
#variation 1 that i tried
#foo = #foo.search(params[:search]) if search(params[:search]).present?
#variation 2 that i tried
#foo = #foo.search(params[:name,:type]) if search(params[:name,:type]).present?
#variation 3 that i tried
#foo = #foo.search(params[:name][:type]) if search(params[:name][:type]).present?
end
Confusion Two
Variation 3 kind of makes the most sense to me. But i dont see the self.search getting called. Also it throws an error (no implicit conversion of Symbol into Integer).
I'm not sure if the error is with my forms too?
Clearly i'm not very proficient with knowing where to pass the params and "collect" them. I've tried reading the ruby documentation but had a hard time understanding it.
I think the bigger picture would be, whats the proper syntax (or way to collect arguments) in a form for a method?
Confusion 1: It doesn't matter what the select_tags are called in your case as you don't seem to have it tied to an actual model attribute, but 'name' and 'type' are quite confusing simply as there are HTML attributes name and type on input fields. Still, it will still work the way you have done it and the 'selected' options look just fine.
Confusion 2: You need to access them individually from the params hash:
#foo.search(params[:name], params[:type]) if params[:name].present? || params[:type].present?
However, you have defined it as a self method as so:
class FooClass
def self.search(name, type)
# blah
end
This means you can't access it on an instance of the class, i.e #foo.search, you would call it from the class itself:
FooClass.search(params[:name], params[:type]) if params[:name].present? || params[:type].present?
If on the other hand you didn't have the 'self', as so:
class FooClass
def search(name, type)
# blah
end
The you could do:
#foo = FooClass.new
#my_var = #foo.search(params[:name], params[:type])
First off change self.search to just search because your index method in your controller is using an instance of your Foo model. when you do self.method that is a class level method and essentially works without having to create an instance of your class, which in this case is your Foo class.
I have added a custom field in my spree_orders table (let's call it custom_attribute).
I have added Spree::PermittedAttributes.checkout_attributes << [:custom_attribute] to my spree.rb initializer.
In my checkout process I have a custom form with the following code (html formatting has been removed):
<%= form_for #order do |alt_form| %>
<%= alt_form.label :custom_attribute, "Custom Attribute" %><span class="required">*</span><br />
<%= alt_form.text_field :custom_attribute, :class => 'form-control required', maxlength: 11 %>
<% end %>
This form successfully submits the field in the post request (full dump below) to http://localhost:3000/checkout/update/address as order[custom_attribute] xyz, however, the information is not saved to the model.
_method=patch
_method=patch
authenticity_token=Y+ATRotWKfI57f+b0/YGwIw9Bg6mADHBDmeEOHYzLPnB6Vbydya4ITDTopcX65EG+TiL7bwyJKQPpBU9bQTaUg==
authenticity_token=Y+ATRotWKfI57f+b0/YGwIw9Bg6mADHBDmeEOHYzLPnB6Vbydya4ITDTopcX65EG+TiL7bwyJKQPpBU9bQTaUg==
commit=Save and Continue
order[bill_address_attributes][address1]=123 Test
order[bill_address_attributes][address2]=
order[bill_address_attributes][city]=Test
order[bill_address_attributes][country_id]=232
order[bill_address_attributes][firstname]=Test
order[bill_address_attributes][id]=3
order[bill_address_attributes][lastname]=Test
order[bill_address_attributes][phone]=555555555
order[bill_address_attributes][state_id]=3535
order[bill_address_attributes][zipcode]=30024
order[email]=spree#example.com
order[custom_attribute]=2414
order[state_lock_version]=32
utf8=✓
utf8=✓
I've inserted #order.inspect on the following (payment) page to can see at that point that #order.custom_attribute is still nil.
Does anyone have any idea about what I need to do in order to get the custom_attribute value sent in the post request saved to the model with the other attributes sent?
-------------------edit-------------------
Default spree permitted attributes are defined here https://github.com/spree/spree/blob/3-0-stable/core/lib/spree/core/controller_helpers/strong_parameters.rb and are added on by the strong_paramaters helper here (don't have the rep to post a third link):
module Spree
module Core
module ControllerHelpers
module StrongParameters
def permitted_attributes
Spree::PermittedAttributes
end
delegate *Spree::PermittedAttributes::ATTRIBUTES,
to: :permitted_attributes,
prefix: :permitted
def permitted_payment_attributes
permitted_attributes.payment_attributes + [
source_attributes: permitted_source_attributes
]
end
def permitted_checkout_attributes
permitted_attributes.checkout_attributes + [
bill_address_attributes: permitted_address_attributes,
ship_address_attributes: permitted_address_attributes,
payments_attributes: permitted_payment_attributes,
shipments_attributes: permitted_shipment_attributes
]
end
def permitted_order_attributes
permitted_checkout_attributes + [
line_items_attributes: permitted_line_item_attributes
]
end
def permitted_product_attributes
permitted_attributes.product_attributes + [
product_properties_attributes: permitted_product_properties_attributes
]
end
end
end
end
end
which can be at found spree/core/lib/spree/core/controller_helpers/strong_parameters.rb in the spree github repo.
-------------------final edit-------------------
If anyone finds this in the future and is trying to troubleshoot a similar issue, my code above is actually correct; I had (stupidly) placed it in an if Rails.env.production? block.
I will give you an example, maybe you can translate it into your code.
OPTIONAL
Imagine that I have a custom action, called "custom" on my users controller, defined this way in my routes:
resources :users do
collection do
get 'custom'
post 'custom'
end
end
This way I can call it by using custom_users_path.
Next, I want a form that submits to that function, to do that you need to specify an additional parameter in your form_for called :url, in this example I call it using custom_users_path, once I submit the form, It will run my custom action.
form_for would look like this:
<%= form_for :user, :url => custom_users_path do |f| %>
<%= f.text_field :random %>
<%= f.submit "Submit" %>
<% end %>
Then, I want to be able to access some :random parameter in my users controller. Let's suppose that I have a text_field which I want store the value on my :random parameter (see above). First, you need to permit that parameter to be accessible in your controller, in this example, in users controller. This way:
params.require(:user).permit(YOUR PARAMETER HERE, {:random => []})
So, every time I submit the form, I can access the :submit parameter value, by doing this params["controller-name"]["parameter-name"], translated into this example, would look like:
params["user"]["random"]
You can then convert it into string using to_s if you want.
Output (Supposing that I wrote "444" on my text_field):
444
I hope this helps you.
So I have a helper method that I am trying to apply css to without putting it in a div or any other element. How would I go about applying the css class to this helper in rails?
I tried:
<%= first_letter_content(e.content), :class => "first-letter" %>
and
<%= (first_letter_content(e.content), :class => "first-letter") %>
both resulting in syntax error, unexpected ',', expecting ')'
Helper code:
def first_letter_content(content)
first_letter = content[0]
return first_letter
end
Any suggestions? I have been trying to find the proper syntax, but no luck.
Your helper does not support options (extra args) but you are trying to give a HTML class to the element.
You should wrap the content of first_letter_content inside a div/span (depending on what you want, block or inline) and apply the class on this HTML element:
<div class='first-letter'>
<%= first_letter_content(e.content) %>
</div>
Or you can directly wrap the content[0] inside a div in the helper method:
def first_letter_content(content, options = {})
content_tag(:div, content[0], options)
end
And use it like this:
first_letter_content(content, class: 'first-letter')
first_letter_content(content, class: 'first-letter', id: 'something')
first_letter_content(content)
Also, you can refactor your helper method to this:
def first_letter_content(content)
content[0]
end
It is a minor improvement but in Ruby the "last thing" used in a method will be returned by this method.
Examples:
def something
a = 2
b = 3
a
end
# => returns `2`
def something_else
a = 2
b = 3
end
# => returns `3`
def whatever
a = 12
nil
end
# => returns `nil`
I am trying to apply css to without putting it in a div or any other element
Css classes are for DOM elements, so you should wrap this content into some element/node.
For example:
def first_letter_content(content, css_class)
content_tag(:div, content[0], class: css_class)
end
Call:
<%= first_letter_content(e.content, "first-letter") %>
I am working on a search with two text fields. It searches for two things (right now location and description) and only shows the entries (listings) that match both of them.
I would like the second text field to also search for title, so it should look for description and title. How would that work?
This is what I have right now
listing.rb
def self.locsearch(search_location, search_description)
return scoped unless search_location.present? || search_description.present?
where(['location LIKE? AND description LIKE?', "%#{search_location}%", "%#{search_description}%"])
end
home.html.erb
<%= form_tag findjobs_path, :controller => 'listings', :action => 'locsearch', method: :get do %>
<%= text_field_tag :location, params[:location] %>
<%= text_field_tag :descripiton, params[:descripiton] %>
<%= submit_tag "Search", name: nil %>
<% end %
listings_controller.rb
def index
#listings = #listings.locsearch(params[:location], params[:description])
end
Also, my locsearch method right now uses the or || condition. How would I implement the "and" condition? (If I change the || to && I get the error" undefined method or variable scroped)
Are you sure you want to use unless
unless is used only if you want to execute a specified code if the condition(s) is false.
And scoped is used along with a model.
Model.scoped
You can refer the Apidock or Github
You can write return scoped only if u have defined scoped as a local variable or a method.
You can also see scope for databases