How to loop rails variable? - ruby-on-rails

I have totally nine buttons in rails. I have input the data into the database by manually typing the #button_1.save function.
My question is:
How can i have the #button_i.save function in rails? I have finished the things in the for loop, what is left is the button save functions.
Many thanks!
button_number = params[:button_number]
for i in (1..button_number)
instance_variable_set("#button#{i}",
Button.new(:title => params["button_title_#{i}".to_sym],
:order => i,
:icon_url => params["button_icon_#{i}".to_sym],
:navigation_id => #navigation.id,
:next_navigation => params["selected_navigation_#{i}".to_sym].to_i,
:next_page => params["selected_page_#{i}".to_sym].to_i))
instance_variable_set("#button#{i}")
end
#button1.save
#button2.save
#button3.save
#button4.save
#button5.save
#button6.save

for i in ...
eval("#button#{i}.save")
end

The opposite of instance_variable_set is instance_variable_get, which I think will lead you to the correct answer:
1.upto(params[:button_number].to_i) do |i|
instance_variable_set("#button#{i}",
Button.new(
:title => params["button_title_#{i}".to_sym],
:order => i,
:icon_url => params["button_icon_#{i}".to_sym],
:navigation_id => #navigation.id,
:next_navigation => params["selected_navigation_#{i}".to_sym].to_i,
:next_page => params["selected_page_#{i}".to_sym].to_i
)
)
instance_variable_get("#button#{i}").save
end

Try by using constantize ruby function because I think your function call statement is in string.
button_number = params[:button_number]
for i in (1..button_number)
instance_variable_set("#button#{i}",
Button.new(:title => params["button_title_#{i}".to_sym],
:order => i,
:icon_url => params["button_icon_#{i}".to_sym],
:navigation_id => #navigation.id,
:next_navigation => params["selected_navigation_#{i}".to_sym].to_i,
:next_page => params["selected_page_#{i}".to_sym].to_i))
"#button#{i}".constantize.save();
end

May be this that you want -
button_number = params[:button_number].to_i
for i in (1..button_number)
instance_variable_set("#button#{i}",
Button.new(:title => params["button_title_#{i}".to_sym],
:order => i,
:icon_url => params["button_icon_#{i}".to_sym],
:navigation_id => #navigation.id,
:next_navigation => params["selected_navigation_#{i}".to_sym].to_i,
:next_page => params["selected_page_#{i}".to_sym].to_i))
instance_variable_set("#button#{i}")
"#button#{i}".save
end

Related

Time frame for displaying user count is not working in Rails 4.2

I am having a dashboard which shows the user created / deleted count of today, yesterday, this week, this month etc;
For this they wrote a condition in controller to get these counts and also scopes in model.
The above scenario is working fine in Rails 3.2 but not working in Rails 4.2.
This is my code:
controller:
protected
def get_user_counts(conditions = {})
includes = []
if conditions.empty?
# nothing
elsif conditions.keys.first.include?("accounts.")
includes = [:account]
end
result = []
[
{:label => 'today', :start => Time.zone.now.beginning_of_day, :end => Time.zone.now.end_of_day},
{:label => 'yesterday', :start => 1.days.ago.beginning_of_day, :end => 1.days.ago.end_of_day},
{:label => 'this week', :start => Time.zone.now.beginning_of_week, :end => Time.zone.now.end_of_week},
{:label => 'last week', :start => 7.days.ago(Time.zone.now.beginning_of_week), :end => 7.days.ago(Time.zone.now.end_of_week)},
{:label => 'this month', :start => Time.zone.now.beginning_of_month, :end => Time.zone.now.end_of_month},
{:label => 'last month', :start => Time.zone.now.prev_month.beginning_of_month, :end => Time.zone.now.prev_month.end_of_month},
].each do |time_frame|
result << [time_frame[:label], User.includes(includes).where(conditions).only_deleted.deleted_between(time_frame[:start], time_frame[:end]).count, User.includes(includes).where(conditions).with_deleted.created_between(time_frame[:start], time_frame[:end]).count]
end
return result
end
model:
scope :created_between, lambda { |start_at, end_at|
{ :conditions => {'users.created_at' => (start_at..end_at)} }
}
scope :deleted_between, lambda { |start_at, end_at|
# Don't forget to use 'count_only_deleted' or 'find_only_deleted' in combination
# with this, or you'll always return zero users. :with_deleted and :only_deleted
# keys do not work in named_scope.
{ :conditions => {'users.deleted_at' => (start_at..end_at)} }
}
Is there any wrong in my code or need any modifications, especially in model scope? Please help.
Problem is with scopes.Eager loading of scopes in Rails 4 has been restricted.
You can change your scope like this :
scope :created_between, -> (start_at, end_at) { where(created_at: (start_at..end_at)) }

Rails splited code not working

I am using rails 2.3. In my application it uses
val = Party.find(:all, :conditions => [" type in ('Physician') || id in (?)",PartyLabel.find(:all,:conditions=>"label_id=#{Label.find_by_label("Can Schedule").id}").collect{|p| p.party_id if Party.find(p.party_id).respond_to?("provider_organizations")}], :with_disabled => true).select{|physician| not physician.provider_organizations.blank? }.collect{|enum| [enum.display_name_schedule, enum.id]}
code to achieve some requirements. Now i wants to split the code in to 2 parts.
1. phys = Physician.find(:all, :include => :provider_organizations, :with_disabled => true).select{|physician| not physician.provider_organizations.blank? }.collect{|enum| [enum.display_name_schedule, enum.id]}
it's working fine.. and the second part will be
2. sch = Party.find(:all, :include => [:as_labels], :conditions => {:label => {:label => "Can Schedule"}}.respond_to?("provider_organizations")).select{|physician| not physician.provider_organizations.blank? }.collect{|enum| [enum.display_name_schedule, enum.id]}
it shows NoMethodError (undefined method 'provider_organizations' for #<ProviderOrganization:0x1ab81c20>): error message... Any comments could be appreciated..
It looks like respond_to?("provider_organizations") is called for a wrong object. Here is your code #2:
sch = Party.find(
:all,
:include => [:as_labels],
:conditions => {
:label => {
:label => "Can Schedule"
}
}.respond_to?("provider_organizations") # What's this ???
).select{ |physician|
not physician.provider_organizations.blank?
}.collect{ |enum|
[enum.display_name_schedule, enum.id]
}
If I understand it correctly, the respond_to? should be inside the select:
...
).select{ |physician|
physician.respond_to?("provider_organizations") && not physician.provider_organizations.blank?
}.collect{ ...

Calling Model name on it's model

I have an import feature from excel. And I put it on my model which:
def self.import(file, employee_name)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
category = Category.where(:name => row["Category"]).last
if category.blank?
category = Category.create(:name => row["Category"], :is_active => 1)
end
unit = UnitOfMeasure.where(:name => row["Unit"]).last
if unit.blank?
unit = UnitOfMeasure.create(:name => row["Unit"], :is_active => 1)
end
chart_of_account_id=0
stock_output_account=0
if row["Can Sold"]==1
income_account=1
else
income_account=0
end
if row["Can Purchased"]==1
expense_account=1
else
expense_account=0
end
product = Product.create(:plu => row["PLU"], :plu_night_disc => row["PLU Night Disc."], :name => row["Item Desc."], :min_stock => ["Min. Stock"], :product_type => row["Product Type"], :notes => ["Notes"], :sales_price => ["Sales Price"], :night_disc_price => ["Night Disc. Price"], :bottom_price => ["Bottom Price"], :category_id => category.id, :unit_of_measure_id => unit.id, :chart_of_account_id => chart_of_account_id, :stock_output_account => stock_output_account, :income_account => income_account, :expense_account => expense_account, :can_be_sold => row["Can Sold"], :can_be_purchased => row["Can Purchased"], :employee_name => employee_name, :is_active => 1)
end
end
But when I do my import, it doesn't return any error, but my creation of Product it just skipped (look for the long code), when I try change the Product for example to model Country it inserting to database finely. I do confuse of this behaviour. Please any help. Thanks
This behavior you're getting probably means you have an invalid Product record, and the insertion is failing silently. Try using the create! method instead:
product = Product.create!(...)
This method will raise an error if your model is invalid, with explanations on why. You can use that information to debug your code.
Hope that helps.

How to collect in Rails?

baza_managers = BazaManager.find(:all,
:conditions => ["or_unit_id != ?", 1]).collect {
|mou| [mou.email, mou.or_unit_id]}
respondent_emails = Respondent.find(:all).collect {|r| r.email }
ERROR:
from lib/scripts/baza_sync.rb:26:in `each'
from lib/scripts/baza_sync.rb:26
26 line ↓
baza_managers.each do |moi|
if !respondent_emails.include?(moi)
Respondent.create(:email => moi, :user_id => 1, :respondent_group_id => moi)
end
end
ERROR I GET:
undefined method `email' for ["vadasd#test.test.com", 8]:Array (NoMethodError)
I don't know why I'm getting this error.
try with:
baza_managers = BazaManager.find(:all,
:conditions => ["or_unit_id != ?", 1]).collect {
|mou| [mou.email, mou.or_unit_id]}
respondent_emails = Respondent.find(:all).collect {|r| r.email }
baza_managers.each do |moi|
if !respondent_emails.include?(moi[0])
Respondent.create(:email => moi[0], :user_id => 1, :respondent_group_id => moi[1])
end
end
Fix your code with following:
if !respondent_emails.include?(moi[0])
Respondent.create(:email => moi[0], :user_id => 1, :respondent_group_id => moi[1])
end
I would think there is at least one error not in the way you are using collect but in the logic you write on the last lines when you go through the baza_managers array.
With this code the condition respondent_emails.include?(moi) will be always false because respondent_emails is an array of email addresses but moi is an array like ["vadasd#test.test.com", 8] so they will never match.
I think this mistake made you make an error in the line :
Respondent.create(:email => moi, :user_id => 1, :respondent_group_id => moi)
Because this line will be evaluate as (for example) :
Respondent.create(:email => ["vadasd#test.test.com", 8], :user_id => 1, :respondent_group_id => ["vadasd#test.test.com", 8])
Which is probably not what you want.
Last, I would suggest you to read the debugger rails guide, I often use debugger to figure out where and what is the problem in this kind of code and error.
I would rewrite your code as follows:
baza_managers = BazaManager.all(:conditions => ["or_unit_id != ?", 1]).
collect { |mou| [mou.email, mou.or_unit_id]}
respondent_emails = Respondent.find(:all).collect {|r| r.email }
baza_managers.each do |email, unit_id|
unless respondent_emails.include?(email)
Respondent.create(:email => email, :user_id => 1,
:respondent_group_id => unit_id)
end
end
This solution can be further optimized by using OUTER JOIN to detect missing Respondents
BazaManager.all(
:include => "OUTER JOIN respondents A ON baza_managers.email = A.email",
:conditions => ["baza_managers.or_unit_id != ? AND A.id IS NULL", 1]
).each do |bm|
Respondent.create(:email => bm.email, :respondent_group_id => bm.or_unit_id,
:user_id => 1)
end
The solution can be made elegant and optimal by adding associations and named_scope.
class BazaManager
has_many :respondents, :foreign_key => :email, :primary_key => :email
named_scope :without_respondents, :include => :respondents,
:conditions =>["baza_managers.or_unit_id != ? AND respondents.id IS NULL", 1]
end
Now the named_scope can be used as follows:
BazaManager.without_respondents.each do |bm|
Respondent.create(:email => bm.email, :respondent_group_id => bm.or_unit_id,
:user_id => 1)
end

rails active record - complicated conditions clause

this works:
ids = [1,2]
varietals = Varietal.find(:all, :conditions => [ "id IN (?)",ids])
But what I want to do is that plus have a condition of: deleted => false
varietals = Varietal.find(:all, :conditions =>{ :deleted => false})
any ideas?
am i going to have to use find_by_sql?
I would handle this with a named_scope to communicate intent and foster re-use:
named_scope :undeleted,
:conditions => { :deleted => false }
Then you can simply use:
varietals = Varietal.undeleted.find([1,2])
You can do it a few ways, but this is the most straight forward:
varietals = Varietal.find( [1,2], :conditions => { :deleted => false })
You can see in the docs that the first parameter of find can take an integer or an array.
ids = [1,2]
varietals = Varietal.find(:all, :conditions => {:id => ids, :deleted => false})
This should work, haven't tested it though.
From the docs:
An array may be used in the hash to
use the SQL IN operator:
Student.find(:all, :conditions => { :grade => [9,11,12] })

Resources