When a potential User is editing their Profile, they have an option to show/hide some information from public view. I did that with
<div class="field">
<%= f.text_field :contact %>
<%= f.select(:contact_type_id, ContactType.all.map {|l| [l.name, l.id]}) %>
<%= f.check_box :visible %>
<%= f.label :visible, "Vidljivo" %>
<%= f.link_to_remove "Izbriši kontakt" %>
</div>
in a partial that's called in the view like this
<%= f.fields_for :contacts do |l| %>
<%= render 'contacts_form', f: l %>
<% end %>
What I now want is to display on a public profile page only that information that the User marked as visible, and I tried it through a different partial
<div class="field">
<% if :visible == true %>
<%= f.text_field :contact %>
<% end %>
</div>
called from
<%= f.fields_for :contacts do |l| %>
<%= render 'contacts_show', f: l %>
<% end %>
but it doesn't work. I tried tons of variations, but it all came down to guessing the right syntax. How do I display only those entries which visibility is marked as "true"?
Why are you displaying the public profile as a form? If you only want to show the information you can iterate over the contact information of the user where the contact type is visible.
I solved it by using a different approach. In my user controller I defined an instance variable #visible and passed it the array consisting of all database entries that have visible parameter set to true. Then I used #visible.each in the view to print the desired content.
Related
I am new to Ruby on Rails. I am building a basic application for learning purpose.
I build a form and when I use the Save button, a record is created but it is a empty record with only an Id.
I hope someone can help me.
routes.rb
Rails.application.routes.draw do
get 'welcome/index'
resources :relaties
root 'welcome#index'
new.html.erb
<h1>Nieuwe Relatie</h1>
<%= form_for :relatie, url: "/relaties" do |f| %>
<p>
<%= f.label :naam %><br>
<%= f.text_field :naam %>
</p>
<p>
<%= f.label :straatnaam %><br>
<%= f.text_field :straatnaam %>
</p>
<p>
<%= f.label :huisnummer %><br>
<%= f.text_field :huisnunmmer %>
</p>
<p>
<%= f.label :postcode %><br>
<%= f.text_field :postcode %>
</p>
<p>
<%= f.label :plaats %><br>
<%= f.text_field :plaats %>
</p>
<p>
<%= f.label :omschrijving %><br>
<%= f.text_area :omschrijving %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
relaties_controller.rb
class RelatiesController < ApplicationController
def new
#relatie = Relatie.new
end
def create
#relatie = Relatie.new(params[:relatie])
#relatie.save
redirect_to(#relatie)
end
private
def relatie_params
params.require(:relatie).permit(:naam, :straatnaam, :huisnummer, :postcode, :plaats, :omschrijving)
end
def show
#relatie = Relatie.find(params[:id])
end
end
While creating/ updating a record you should whitelist the attributes that you would like to be saved in database. You have added a method named relatie_params to do that BUT you have not used it in the code which is why when you try to create a new Relatie record none of the attributes are stored in database as they are not white-listed.
In create action, replace
#relatie = Relatie.new(params[:relatie])
with
#relatie = Relatie.new(relatie_params)
For your reference, read about Strong Parameters which was introduced in Rails 4
In my app, there is a comment section on articles. I'd like the user to have the ability to comment with 3 different options. To activate this, I am using an Active Record Enum. Please note that the comment sections is nested under the articles.
resources :articles, only: [:index, :show] do
resources :comments
end
Migration:
class AddEnumToCommentModel < ActiveRecord::Migration
def change
add_column :comments, :post_as, :integer, default: 0
end
end
Comment model:
enum post_as: %w(username, oneliner, anonymous)
I attempted to add this to the content view, but lost. I am guessing I also have to do something in my controller but not sure.
Attempted view :
<%= form_for([#article, #comment]) do |f| %>
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% #comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<h3>Fill in your comment</h3>
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="post_as">
<h3> Choose how you want to post your comment :</h3>
<%= f.input :content, post_as: ???, as: :radio %>
</div>
<br>
<div class="actions">
<%= f.submit %>
</div>
<br>
<% end %>
Rails creates a class method using the pluralized attribute name when you use enum. The method returns a key value pair of strings you've defined and what integers they map to. So, you could do something like this:
<% Comment.post_as.keys.each do |post_as| %>
<%= f.radio_button :post_as, post_as %>
<%= f.label post_as.to_sym %>
<% end %>
There's also collection_radio_buttons, which is more succinct than the other options.
<%= f.collection_radio_buttons :post_as, Comment.post_as, :second, :first %>
Those last two arguments specify how to get the input's value and label text. In your example Comment.post_as produces a hash of enum key names to the underlying integer, so we can grab those using :second for the integer and :first for the name — easy!
Here's what that produces:
<input type="radio" value="0" name="comment[post_as]" id="comment_post_as_0">
<label for="comment_post_as_0">username</label>
# Etc.
You can also customize the HTML by passing a block, which is my preferred way to create enum radio buttons with clickable labels:
<%= f.collection_radio_buttons :post_as, Comment.post_as, :second, :first do |b|
b.label { b.radio_button + b.text }
end %>
An addition to xxyyxx's answer, if you want the labels to be clickable as well:
<% Comment.post_as.keys.each do |post_as| %>
<%= f.radio_button :post_as, post_as %>
<%= f.label "#{:post_as}_#{post_as.parameterize.underscore}", post_as %>
<% end %>
In the view instead of
<%= f.input :content, post_as: ???, as: :radio %>
you could have
<%= f.radio_button(:post_as, "username") %>
<%= label(:post_as, "Username") %>
<%= f.radio_button(:post_as, "oneliner") %>
<%= label(:post_as, "Oneline") %>
<%= f.radio_button(:post_as, "anonymous") %>
<%= label(:post_as, "Anonymous") %>
Source: http://guides.rubyonrails.org/form_helpers.html#radio-buttons
I have a nest form that is working great. The form is basically a customer with addresses.
I am trying to render a partial at both the customer and address level to indicate who created each record and who was the last person to update the record.
My view code is:
<%= form_for(#customer) do |f| %>
<%= render 'cust_fields', f: f %>
<%= render 'layouts/audit', audit: #customer %>
<strong>ADDRESSES:</strong>
<hr />
<%= f.fields_for :addresses do |a| %>
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: :addresses %>
<% end %>
<% end %>
The code in question is <%= render 'layouts/audit', audit: :addresses %>
This is throwing the the error:
undefined method `created_by' for :addresses:Symbol
I have tried to change :addresses to #customer.addresse but that doesn't work either. Why?
My partial code is:
<% created_user = User.find(audit.created_by) %>
<% updated_user = User.find(audit.updated_by) %>
<div class="row audit-info">
<small>
<div class="pull-left">
Created by: <%= created_user.name %>
</div>
<div class="pull-right">
Last updated by: <%= updated_user.name %>
</div>
</small>
</div>
Both the customers and addresses table have created_by and updated_by columns.
Any help would be much appreciated.
I was able to get this working by introducing the following code in my view:
<% for i in 1..#customer.addresses.size %>
<%= f.fields_for #customer.addresses[i-1] do |a| %>
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: #customer.addresses[i-1] %>
<% end %>
<% end %>
Actually, the above didn't work since I was double counting the children records.
What did work (after some more research) was the following:
<%= f.fields_for :addresses do |a| %>
<div class="deleterow">
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: #customer.addresses[a.index] %>
</div>
<% end %>
The key was using a.index, which can be seen on line 4.
I have a mongo rails 4 app, with an embedded photo.
I have no problem in the new form, but in the edit form, if the user has not upload any photo, the form will not display a "add photo button".
Here is the form:
<%= f.fields_for :founder_profile_photos do |founder_photo_f| %>
<%= render partial: 'founder_profile_photo_fields', locals: { f: founder_photo_f } %>
<%= link_to_add_association raw('<i class="fi-plus"> add a founder photo</i>'), f, :founder_profile_photos %>
<% end %>
Here is the partial:
<div class="nested-fields">
<% if f.object.file.to_s.empty? %>
<%= f.file_field :file, label: "Upload a founder photo." %>
<% else %>
<%= image_tag f.object.file, class: 'small-10 medium-10 image-previewer' %>
<% end %>
</div>
Thank you so much for your help. I finally found what was wrong, I needed to build the field photo in the edit action of my controller, other the field does not exist and therefore do not appear in the view.
def edit
if #user.photos.empty?
#user.photos.build
end
end
photo is embedded into the user model (one to many relation) if you have a one to one relation you have to do:
if #user.photo.blank?
#user.photo = Photo.new
end
Thank you very much for all your help, still so much to learn.
I have a search form on an index page for my Properties model which is using both Ransack and Geocoder to search the Properties model fields as well as narrow the results down based on distance from an address input by the user in the search form.
The address and distance are captured in the form with :nearaddress and :distance, respectively, which I send in params[:near]. I am checking for the presence of them in the controller index action following this answer. The result is “undefined method `merge' for nil:NilClass” when navigating to /properties, so the view will not render. How do I enable these non-model form parameters to be passed to the controller properly? I think this might be a strong parameters issue but I'm stuck on how to permit these attributes that aren't in the Properties model. The error highlights the "f.text_field :nearaddress" line.
index.html.erb:
...form fields that work when excluding the two that follow...
<div class ="field">
<%= f.label :nearaddress, "Address" %>
<%= f.text_field :nearaddress, params[:near] %>
</div>
<div class ="field">
<%= label_tag :distance %>
<%= text_field_tag :distance, params[:near] %> miles
</div>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
properties_controller.rb:
def index
if params[:near].present? && (params[:near].to_i >0)
#search = Property.near(params[:near]).search(params[:q])
else
#search = Property.search(params[:q])
end
#properties = #search.result(:distinct => true).paginate(:page => params[:page])
...
end
I was able to resolve this problem by removing the "f." and adding "_tag" to the :nearaddress field as well as specifying the params in the controller index:
<%= label_tag :nearaddress, "Near Address" %>
<%= text_field_tag :nearaddress, params[:near] %>
<%= label_tag :distance, "Distance From Address (mi)" %>
<%= text_field_tag :distance, params[:near] %>
<div class="actions"><%= f.submit "Search" %>
<% end %>
if params[:distance].present? && (params[:distance].to_i >0) && params[:nearaddress].present?
#search = Property.near(params[:nearaddress],params[:distance]).search(params[:q])
else
#search = Property.search(params[:q])
end