I am trying to give size properties to a drop down and select a default value. Doesn't seem to work, on the html I see length="35" but it has no effect on the actual width. How do I do this?
#roles = ['admin','user']
collection_select(:user, :title, roles.all, :id, :name, :value => "user", {:length => 35})
collection_select(:user, :title, roles.all, :id, :name, :value => "user", {:width => 35})
You should use :style => "width:200px" instead of :length.
Or much better, to use a css class for that selection box.
Related
I am building a Rails 4.2.4 app where I have Units and Medics. When I edit each unit I have two spots for the medics, incharge and attendant. I want some way to validate that both the incharge_id and attendant_id are not the same. That way I can't assign myself as both positions on the unit.
Here is what my model and form view looks like.
unit.rb
class Unit < ActiveRecord::Base
belongs_to :attendant, :foreign_key => :attendant_id, :class_name => 'Medic'
belongs_to :incharge, :foreign_key => :incharge_id, :class_name => 'Medic'
belongs_to :unit_status
end
medic.rb
class Medic < ActiveRecord::Base
has_many :units
end
units/_form.html.erb
<%= form_for(#unit) do |f| %>
<%= f.label 'Attendant'%>
<%= f.collection_select(:attendant_id, Medic.order('name ASC'), :id, :name, {}) %>
<%= f.label 'In Charge'%>
<%= f.collection_select(:incharge_id, Medic.order('name ASC'), :id, :name, {}) %>
<%= f.label 'Unit Status'%>
<%= f.collection_select(:unit_status_id, UnitStatus.order("status ASC"), :id, :status, {})%>
<%= f.submit "Update" %>
<% end %>
So in summary if I edit a unit and I accidentally assign the id of "1" to the unit, I want to error out and give some sort of message, "Cannot assign the same medic to both positions". Something like that.
The only thing I can think of, is to somehow filter the params in the controller saying if the params of attendant_id and incharge_id are are == then redirect to the edit_unit_path and display a flash message, "You cannot assign the same medic to both positions".
It seems like it would be better to do validations on the model side instead of stuffing logic in the controller, but I'm not sure how to simultaneous validate the two different columns for uniqueness.
I came up with this on the Unit model.
validate :attendant_and_incharge
def attendant_and_incharge
errors.add(:attendant_id, "can't be the same as the incharge") if attendant_id == incharge_id
end
This will not allow me to save the same id to the unit model for attendant_id and incharge_id. It fails silently and directs to the units_path. Just need to put some conditional in the controller to redirect to the edit path on failure. (ThumbsUp)
Using Datamapper with Sinatra, it's really easy to save text properties:
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/tailor.db")
class Person
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
property :height, String, :required => false
end
DataMapper.finalize.auto_upgrade!
...
put '/:id/edit' do
p = Person.get params[:id]
p.name = params[:name]
p.height = params[:height]
p.save
end
And the view:
%form
%input{:type => 'text', :name => 'name'}
%input{:type => 'text', :name => 'height'}
%input{:type => 'submit', :value => 'Save'}
With :type => 'text' it is a breeze. However, I'm running into trouble trying to set a boolean (property :test, Boolean, :required => false) with a checkbox. This question is similar, but doesn't address how to do a simple boolean.
In addition, what is the easiest way to set up values that don't accept any string, but rather just a set of predefined options—either as a select that allows one choice, or a set of radio buttons that allows several?
EDIT:
I figured out checkboxes:
p.bool = !params[:bool].nil?
and in the view:
%input{:type => 'checkbox', :name => 'bool', :value => "#{#bool}", :checked => #p.bool}
When you submit a form with a checkbox, if you don’t specify the value form it the default is the string on. Additionally, if the checkbox isn’t selected it doesn’t get submitted at all. So the result is that in your handler, params[:test] (assuming the checkbox is named test) is either nil if it was unchecked, or the string on if it was.
A boolean property in Datamapper is expecting to be assigned either a Boolean (true or false), or one of a small set of values that it will implicitly convert. on and nil are not among those values, so when you try to assign the value to Datamapper it will fail validation and not save:
...
p.test = 'on'
if !p.save
p p.errors[:test]
end
produces:
["Test must be of type TrueClass"]
One way to fix this is to check in your handler and explicitly convert the value to a boolean when assigning to the property:
p.test = params[:test] == 'on' ? true : false
Another technique is to set the value in the HTML checkbox to one of the values that Datamapper will convert, so you can pass it directly. You can have multiple controls with the same name in a form, and they will be submitted in the order they appear in the page. Sinatra will only use the last one when creating the params hash, so if you add a hidden input with the same name as the checkbox before the checkbox, then if it is not checked the value will be that of the hidden input. If it is checked, its value will override that of the hidden input.
%input{:type => 'hidden', :name => 'foo', :value => 'f'}
%input{:type => 'checkbox', :name => 'foo', :value => 't'}
Now params[:test] will be either 'f' or 't',, both of which Datamapper will convert for you, so you can simply do
p.test = params[:test]
I have installed paperclip and imagemagick,and implemented the code to my model and view file.
I have a database column named 'picture' and it is empty no matter if i uploaded a picture or not. the picture acctually exists in the/public/system/decks/pictures/000/000/019/medium folder. i can see all of the uploaded pictures there, but i can't show them cause the database is empty.
My model:
class Deck < ActiveRecord::Base
attr_accessible :picture
has_attached_file :picture, :styles => { :medium => "300x300>", :thumb => "100x100>" }
attr_accessor :picture_file_name
attr_accessor :picture_content_type
attr_accessor :picture_file_size
attr_accessor :picture_updated_at
My view:
<%= form_for #deck,:url => decks_path, :html => { :multipart => true } do |f| %>
<%= f.file_field :slika %>
My migration:
class AddAttachmentPictureToDecks < ActiveRecord::Migration
def change
add_column :decks, :picture, :attachment
end
end
So i get the picture in that folder that i have mentioned before but the picture column in my decks table is empty. I can't get the picture with <%= image_tag #deck.picture.url(:medium) %>, cause my #deck.picture.url holds a /pictures/original/missing.png, my #deck.picture.path and my #deck.picture.picture_file_name also shows nothing.
Thank you.
in the end it looks like i mixed the old syntax and the new one and i couldn't get the fields right in the database. and it looks like the attr_accessors are unneccessary
How can I make padrino-admin page generator produce beautiful custom pages?
By default padrino-admin generates pretty ugly admin pages, totally unmaintainable:
.group
=f.label :title
=f.error_message_on :title
=f.text_field :title, :class => :text_field
%span.description Ex: a simple text
.group
=f.label :name
=f.error_message_on :name
=f.text_field :name, :class => :text_field
%span.description Ex: a simple text
--- more annoyingly redundant frak
.group.navform.wat-cf
=f.submit pat(:save), :class => :button
=f.submit pat(:cancel), :onclick => "window.location='#{url(:pages, :index)}';return false", :class => :button
I wrote a nice AdminFormBuilder < AbstractFormBuilder, connected it with set :default_builder, 'AdminFormBuilder', it generates same admin pages from very short code:
= f.inputs :name, :surname, :email
= f.inputs :password, :password_confirmation, :as => :password
= f.input :role, :as => :select, :options => access_control.roles, :descr => 'a simple text'
= f.submits
Now I want padrino g admin_page to generate more of such pages. What should I do?
There are two ways:
1) Make your custom admin gem copying as base the actual padrino-admin
2) Fork the project (where now we support a new admin based on bootstrap) apply your changes and submit a pull request.
Btw the most interesting file for this job is this: https://github.com/padrino/padrino-framework/blob/master/padrino-admin/lib/padrino-admin/generators/admin_page.rb
Here is one-line patch for padrino-admin gem: https://github.com/ujifgc/padrino-framework/commit/b07399bdfbc15d05682237c64580e77558ac9fce
Now I can place copy of original templates folder from padrino-admin-0.10.5/lib/padrino-admin/generators to vendor/padrino-admin/generators and enjoy my own admin page templates.
First come caveats. I'm a total RoR n00b but i have experience with programming so i get the basic's. I've got an application i'm building which i need to build a complex search engine for. The basic layout is Guides >> Profiles >> Mentorings >> MentorAreas. Below is the code for each of the models and then the code i'm trying to build. My issue is i can't seem to figure out the proper object name to get the search engine to search mentor_areas.
System Setup:
rails -v :: Rails 3.1.1
ruby -v :: ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0]
RanSack :: ransack (0.5.8) from git://github.com/ernie/ransack.git (at master)
Guide:
class Guide < User
end
User: (what's relevant)
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Virtual attribute for authenticating by either username or email
# This is in addition to a real persisted field like 'username'
attr_accessor :login
# Setup accessible (or protected) attributes for your model
attr_accessible :login, :username, :email, :password, :password_confirmation, :remember_me, :sex,
:location, :role, :first_name, :last_name, :home_town, :profile_attributes
has_one :profile, :dependent => :destroy
accepts_nested_attributes_for :profile, :allow_destroy => true
has_and_belongs_to_many :roles
end
Profile
class Profile < ActiveRecord::Base
belongs_to :user
has_many :mentor_areas, :through => :mentorings
has_many :mentorings
accepts_nested_attributes_for :mentor_areas,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }, :allow_destroy => true
validates_uniqueness_of :user_id
end
Mentoring
class Mentoring < ActiveRecord::Base
belongs_to :mentor_area
belongs_to :profile
validates_uniqueness_of :profile_id, :scope => :mentor_area_id
end
MentorArea
class MentorArea < ActiveRecord::Base
has_many :profiles, :through => :mentorings
has_many :mentorings
validates_uniqueness_of :mentor_area
end
In my Guides Controller i have:
#search_guides = Guide.joins(:roles).where("sex = :sex AND roles.name = :role",{:sex => current_user.sex, :role => 'guide'}).search(params[:search])
#guides_found = #search_guides.all
and in my view (index.html.erb) i have the following:
<%= form_for #search_guides do |f| %>
<%= f.label :username_cont %>
<%= f.text_field :username_cont %><br />
<%= f.label :guides_profiles_mentor_areas_mentor_area_cont %>
<%= f.text_field :guides_profiles_mentor_areas_mentor_area_cont %><br />
<%= f.submit %>
<% end %>
I can't seem to figure out what the correct name should be for the second field so that it will search against the mentor_areas that a person has associated with there profile.
thanks in advance!
Updated for RanSack Code
If I'm reading your code correctly, you want:
:profile_mentor_areas_mentor_area_cont
I think it's:
:profiles_mentorings_mentor_area_mentor_area_contains
Basically, it's you have to think about which tables you have to reach through one by one in sequence to get to your search field. I think in your case, your view for guides needs to go through : profiles -> mentoring -> mentor_area in order to search for the mentor area? Your mentor_area only have profiles :through the mentoring model. You can't go directly to the mentor_are without going through the mentoring model first.
Also,
<%= f.label :guides_profiles_mentor_areas_mentor_area_contains %>
looks really cumbersome in the view. You can just say this instead:
<%= f.label "Mentor Area" %>
Hope that works.