无法在数据库中创建记录

时间:2015-05-01 09:36:57

标签: mysql ruby-on-rails ruby database controller

我使用rails版本4.2和ruby版本2.2.0。我正在尝试将记录保存到 lollypops 表。没有例外说明原因。

任务:只要创建并保存了member,我就想通过调用成员控制器中的lollypops来填充 create_lollypop(@member.id) 表。 ; s create这样的方法:

 #   POST /members
 #   POST /members.json
  def create

 @member = Member.create(members_params)                               
   return unless request.post?

   @member.save!
   self.current_user = @member
   c = Country.find(@member.country_id)
   @member.update_attributes(
   :country_code=>c.code)
   create_lollypop(@member.id) #From here I want to create lollypop
   MemberMailer.signup_notification(@member).deliver_now

   redirect_to(:controller => '/admin/members', :action => 'show',
   :id=> @member.id)
   flash[:notice] = "Thanks for signing up! Check your email now to 
   confirm that    your email is correct!"

   rescue ActiveRecord::RecordInvalid
   load_data
   render :action => 'new'

  end

def create_lollypop(member_id)
 @member = Member.find(member_id)      
    Lollypop.create(
    :member_id=>@member.id,
    :product_name=>'lollypop',
    :product_price=>100,
    :email=>@member.email,
    :house_flat => @member.house_flat,    
    :street=>@member.street,
    :city_town=>@member.city_town,
    :country =>@member.country,   
    :postcode_index=>@member.postcode_index,
    :name=>@member.name)
end 

'成员'已经创建了但是“棒棒糖”#39;表未填充。协会是:

会员模型:

 has_one :lollypop, :dependent=>:destroy

LOLLYPOP模型

  belongs_to :member

如果我使用通用SQL命令,则会填充lollypops表,但我不想这样做:

def self.create_lollypop(member_id)
   member = Member.find(member_id) 
ActiveRecord::Base.connection.execute("insert into lollypops (member_id,product_name,product_price,email,house_flat,street,city_town,country,postcode_index,name)
   values(#{member.id},'lollypop',#{100},'#{member.email}','#{member.house_flat}','#{member.street}','#{member.city_town}','#{member.country_code}','#{member.postcode_index}','#{member.name}')")  

end 

任何建议都会受到欢迎。谢谢。

4 个答案:

答案 0 :(得分:0)

在你的create_lollypop()中,你没有定义@member。

    <?php
            $sql = "SELECT id, brand FROM vechiles";
            $result = $conn->query($sql);

            if ($result->num_rows > 0) {
                while($row = $result->fetch_assoc()) {

                    $sql1 = "SELECT * FROM fotos WHERE vechiles_id =". $row['id'];
                    $result1 = $conn->query($sql1);

                    echo '<li><p class="title">'. $row['brand'] .'</p>
                            <p class="type">type: 2387</p>
                            <p class="ez">ez: 1987</p>';

                            if ($result1->num_rows > 0) {
                             // output data of each row
                            while($row1 = $result1->fetch_assoc()) {
                                echo '<img src="admin/'. $row1['url'] .'" atl="tractor 1"/>';
                            }}else{
                                echo "there are no pictures";
                            }

                            echo '<div class="info">
                            <p class="prijs">Prijs: 1800,- EX BTW</p>
                            <p class="msg"> Prijzen onder voorgehoud</p>
                            </div>
                            <a class="button" href="#">Meer info</a></li>';
                }
            } else {
                echo "0 results";
            }
            $conn->close();
        ?>

也可以使用创建!所以如果任何验证失败,那么它将引发异常。所以它可以帮助你解决问题。

答案 1 :(得分:0)

暂时尝试使用关联方法create_lollypop直接在控制器中创建lollypop。在你创建控制器方法时使用这段代码,注意create_lollypop方法会自动填充(member_id字段):

@member = Member.create(members_params)                               
   return unless request.post?

   @member.save!
   self.current_user = @member
   c = Country.find(@member.country_id)
   @member.update_attributes(
   :country_code=>c.code)
   #From here I want to create lollypop
   @member.create_lollypop(
     :product_name=>'lollypop',
    :product_price=>100,
    :email=>@member.email,
    :house_flat => @member.house_flat,    
    :street=>@member.street,
    :city_town=>@member.city_town,
    :country =>@member.country,   
    :postcode_index=>@member.postcode_index,
    :name=>@member.name
    )
   MemberMailer.signup_notification(@member).deliver_now

   redirect_to(:controller => '/admin/members', :action => 'show',
   :id=> @member.id)
   flash[:notice] = "Thanks for signing up! Check your email now to 
   confirm that    your email is correct!"

   rescue ActiveRecord::RecordInvalid
   load_data
   render :action => 'new'

答案 2 :(得分:0)

这不是一个答案,更像是提示和笔记,它有点长,我希望你不要介意。

  • return unless request.post?
    

    这更像是一个php的东西而不是rails的东西,在rails已经路由正在检查这个,所以你不需要在控制器里面做这个检查,如果它不是{{1它将被路由到其他地方。

  • post

    创建后保存是没有意义的,因为创建已保存数据,如果你是为了爆炸@member = Member.create(members_params) return unless request.post? @member.save! 而这样做,那么你可以使用创建与爆炸save!,更不用说了你在会员创建之后进行了重定向检查,所以如果这确实有效,就会让你留下流浪的成员。

  • create!

    如果您的关联正确,则不需要像这样保存代码,因为该成员知道此c = Country.find(@member.country_id) @member.update_attributes(:country_code=>c.code) 属于某个国家/地区。

    所以将此添加到成员模型

    country_id

    通过这种方式,您可以随时调用class Member < ActiveRecord::Base has_one :lollypop, dependent: :destroy belongs_to :country end 来返回国家/地区对象,然后代码可以来自那里,例如@member.country,或者您可以只编写一种方法来缩短它

    @member.country.code

    这种方式可以通过额外的查询获取代码,但它有一个优势,如果您因任何原因更改了国家/地区的代码,您就不需要循环拥有该国家/地区的所有成员并且还要更新他们的代码,您还可以使用def country_code country.code end

  • 进一步缩短代码
  • #delegate

    在这里你是在保存成员后更新成员的属性,这有点浪费,因为你正在做2个查询,可以用1个查询完成,编程上它是正确的,它会起作用,但它是&#39 ;对于扩展不利,当更多用户开始使用您的应用时,数据库将更加繁忙,响应速度将会变慢。

    相反,我会建议推迟成员的创建,直到你拥有你想要的所有数据

     @member.save!
     @member.update_attributes(:country_code=>c.code)
    

    当所有数据都准备好保存时,这只会在最后进行1次查询。

  • @member = Member.new(members_params) # this won't save to the database yet
    @memeber.code = Country.find(@member.country_id).code
    @member.save
    

    这没关系,但您可能在路线中有更好的短路径名称,例如redirect_to(:controller => '/admin/members', :action => 'show', :id=> @member.id) ,在终端中执行members_admin_path检查路线名称。

    bin/rake routes
  • redirect_to members_admin_path(id: @member)
    

    我不确定这是否可行,因为需要返回重定向,但是当你在它之后添加闪存时,重定向将在没有闪存的情况下发生,或者闪存将被设置并返回,因为它& #39;是最后一个声明,但重定向不会发生,不知道会发生什么,修复它你只需交换两个语句,先创建flash然后重定向,或者使用更方便的方式在重定向时设置闪光灯,导致支持

    redirect_to ...
    flash[:notice] = "message"
    
  • redirect_to ....., notice: 'my message'
    

    这将完成这项工作,但它不常见,人们倾向于使用软rescue ActiveRecord::RecordInvalid load_data render :action => 'new' ,然后对返回值执行if条件,无论是真还是假,这里&#39; sa简短布局

    save
  • 棒棒糖创作
    现在有一些事情,首先你在控制器中有方法,这是不好的因为它不应该是控制器的关注,第二种方法# prepare @member's data if @member.save # set flash and redirect else load_data render :new end 更好因为它是在模型级别创建的,但它是一个类方法,那么更好的方法是将其创建为成员方法,这样创建self.create_lollypop的成员已经知道了数据,因为它是他自己的,请注意我不需要拨打lollypop,因为我已经在会员中,所以像@memberid这样的简单电话将会返回会员和&#{1}} #39; s数据

    email

    如果您愿意,也可以将其添加为创建后回调

    # inside member.rb
    def create_lollypop
      Lollypop.create!(
        member_id: id,
        product_name: 'lollypop',
        product_price: 100,
        email: email,
        house_flat: house_flat,
        street: street,
        city_town: city_town,
        country: country,   
        postcode_index: postcode_index,
        name: name
      )
    end
    

    ps:此方法名称可能与ActiveRecords after_create :create_lollypop 方法冲突,因此您可能应为此方法选择其他名称。

答案 3 :(得分:0)

正如穆罕默德向我建议的那样,我将Lollypop.create改为Lollypop.create!和 在运行我的代码时,弹出一个验证错误。纠正之后 将我的代码改为:

 Lollypop.create!( 
 :member_id=> @member.id,  
 :product_name=>'lollypop',
 :product_price=>100,
 :email=>@member.email,
 :house_flat => @member.house_flat,    
 :street=>@member.street,
 :city_town=>@member.city_town,
 :country =>@member.country_code,   
 :postcode_index=>@member.postcode_index,
 :name=>@member.name
)

&#39; lollypops&#39;桌子已经填满了。

enter image description here