in domainpost.rb i have this:
class Domainpost < ActiveRecord::Base
attr_accessible :content, :additiona, :registerdate, :expiredate, :registerin, :price
belongs_to :user
before_save { |domainpost| domainpost.content = content.downcase }
before_validation :pricecheck
validates :price, allow_blank: false, presence: true
default_scope order: 'domainposts.created_at DESC'
def pricecheck
if price.blank?
price = 'no price'
end
end
and it isnt work
when price in post is blank after save is stil blank,
any idea what i do wrong?
It doesn't work because instead of setting attribute price of Domainpost instance, you set a local variable. Instead you should do:
def pricecheck
self.price = 'no price' if price.blank?
end
As answer by #Merek Lipka and #muttonlamb you can try those approach but I suggest is defined a default value on your database side
like on your migration for price field simply do this
t.[price_data_type],:price,:default => "Your Default value"
Well this will take care of your check in model I believe
Related
I currently have the following method:
def complete?
attributes.delete_if{|k,v| k == 'id' or k == 'user_id'}.values.each do |value|
return false if value.blank?
end
true
end
Is there a better way of doing this? I just want to know if, with my instance, all the attributes have been set apart from id and user_id. There must be a better way of doing this.
I'm on rails 3 and ruby 1.9.3 (just so people don't give answers that will work with newer versions)
There is the validates method to do that:
class User < ActiveRecord::Base
validates :full_name, :username, :email, :address, presence: true
If you want to validate the presence of every attributes except few ones:
class User < ActiveRecord::Base
validates *(self.column_names - ['id', 'created_at', 'updated_at']), presence: true
Above exemple extended:
class User < ActiveRecord::Base
validates *self.validable_columns, presence: true
def self.validable_columns
excluded_columns = ['id', 'created_at', 'updated_at'] # columns to be excluded in the `validates`
self.column_names - excluded_columns
end
I have a categories model. I want to ensure that a user doesn't add a duplicate category name to his/her list of categories.
Here's my categories model:
class Category < ActiveRecord::Base
belongs_to :user
validates :name, presence: true
validates :user_id, presence: true
before_validation :validate
private
def validate
errors.add(:name, "is already taken") if Category.where("name = '?' AND user_id = ?", self.name, self.user_id).any?
end
end
Here is my RSpec test:
it "is invalid with duplicate name for same user" do
existing_category = Category.first
new_category = Category.new(:name => existing_category.name, :user_id => existing_category.user_id)
expect(new_category).to have(1).errors_on(:name)
end
Should I use before_save or before_validate? Also, I'm unsure how to write this. I guess if a duplicate is detected, I want to add an error for :name. Above is my attempt but doesn't seem to make it pass, is there anything obviously wrong? Also, is this good practise for adding custom validation?
Here is a much simpler way to achieve your goal - you can use scope option of validates_uniqueness_of validator:
validates_uniqueness_of :name, scope: :user_id
Your spec fails because it has an error. It expect new_category has error, but it doesn't run validations on this object. To do that, you just need to add:
new_category.valid?
before expect#... line.
My app allows users to add words from a master words table into their own custom list. So, a word list contains multiple custom words each of which link to a master word.
In my view, I have a field called word_text (virtual attribute) where I let users enter a word, and in my model I am trying to look up the master_word_id and set it on the custom word table. I am unable to access the #word_text value in the model. I always seem to get an error that the master word is a required field (because the look up is failing).
class CustomWord < ActiveRecord::Base
attr_accessible :master_word_id, :word_list_id, :word_text
attr_accessor :word_text
belongs_to :word_list
belongs_to :master_word
validates :word_list, presence: true
validates :master_word, presence: true
before_validation :set_master_word
private
def set_master_word
logger.debug "Received word text #{#word_text}"
_mw_id = nil
if !#word_text.nil?
master_word = MasterWord.find_word(#word_text)
if master_word.nil?
errors.add("#{#word_text} is not a valid word")
else
_mw_id = master_word.id
end
end
self.master_word_id = _mw_id
end
end
I sincerely appreciate any suggestions as to how I can set the value of the master_word_id correctly.
There are several things to fix:
class CustomWord < ActiveRecord::Base
attr_accessible :master_word_id, :word_list_id, :word_text
attr_accessor :word_text
belongs_to :word_list
belongs_to :master_word
validates :word_list, presence: true
#validates :master_word, presence: true <= This will always throw error
validates :word_text, presence: true
validates :master_word_id, presence: true
before_validation :set_master_word
private
def set_master_word
logger.debug "Received word text #{self.word_text}"
self.master_word_id = MasterWord.find_by_word_text(self.word_text).id
end
end
Not sure if it will work because I don't know the rest of your app but I hope it points you in the right direction.
I'm having hard time with this, it's not a direct problem of implementation but I don't understand which is the right way to do it, I have two options, but first, these are my models:
class Boat < ActiveRecord::Base
validates :name, presence: true, uniqueness: { case_sensitive: false }
has_many :tech_specs, order: 'position'
def visible?
self.visible
end
end
class TechSpec < ActiveRecord::Base
validates :boat_id, presence: true
validates :tech_spec_name_id, presence: true, uniqueness: { scope: :boat_id }
belongs_to :boat
belongs_to :tech_spec_name
before_destroy :destroy_name_if_required
acts_as_list scope: :boat
def as_json(options = {})
super(options.except!(:tech_spec_name_id).merge!(methods: [self.name]))
end
def name
self.tech_spec_name.try(:name) || ''
end
def name=(value)
self.tech_spec_name = TechSpecName.find_or_create_by_name(value)
end
def destroy_name_if_required
self.tech_spec_name.destroy if self.tech_spec_name.tech_specs.size <= 1
end
end
class TechSpecName < ActiveRecord::Base
validates :name, presence: true, uniqueness: { case_sensitive: false }
has_many :tech_specs
def self.with_name_like(str)
where('lower(name) LIKE lower(?)', "%#{ str }%")
end
end
The problem is that I want a page for a boat showing some tech specs when with a locale and when on a different locale, showing other tech specs.
Idea #1
My basic idea is to add to TechSpec globalize3 on tech_spec.value and on TechSpecName for field tech_spec_name.name
Idea #2
The other idea is to remove TechSpecName and, instead, use a field (tech_spec.name) that will "replace" completely TechSpecName. Notice that in this case, I'll still need to fetch names for autocomplete, but I will filter them in TechSpec instead of fetching all from TechSpecName. This field will use globalize3 again obviusly.
I don't know the downside of both approaches, so I need a suggestion.
Seems like idea #1 is ok, it works correctly and reduce the amount of repeated text inside Db.
I18n.with_locale helps a lot too, also Globalize.with_locale is helpful
In my models, BookHeader has many Category
So, when edit or create new BookHeader, the form show like this
Enum fix?
I wanna change the "category #{id}" to category name by define a category_enum method but it still don't work. Please help!
Code for BookHeader model
class BookHeader < ActiveRecord::Base
attr_accessible :autho, :category_id, :description, :title, :book_type, :year,:publisher_id,:detail
has_many :books
belongs_to :category
belongs_to :publisher
TYPE = {:ebook=>"Ebook",:paper_book=> "PaperBook",:magazine=> "Magazine",:media=> "Media"}
DEFAULT_TAB = :paper_book
BOOKS_PER_PAGE = 1 # books to show in a pages (pagination)
extend FriendlyId
def book_type_enum #it worked here
TYPE.map{|key, val| [val]}
end
def category_enum #but dont' work here
["a","b"]
end
Code for edit form
edit do
field :title
field :description, :text do
ckeditor do true end
end
field :autho
field :book_type
field :category
end
See the Division attribute in this link
alias_attribute :name, :you_field_you_want_to_display
I think it's more flexible way, there is no need to rename something and everything will work properly
Yeah, I just found the answer, rename a column in your model to "name", it seem to be very magical, but it worked!